Beispiel #1
0
void printBuffer(volatile uint16_t *data, int start, int size) {
	int i;
	for (i = start; i < start + size; i++) {
		printChar('\t');
		printInt32(data[i]);
	}					
	printChar('\n');		
}
static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O)
{
	SStream_concat0(O, "[");
	printInt32(O, (int)MCOperand_getImm(MCInst_getOperand(MI, OpNum)));
	SStream_concat0(O, "]");
	if (MI->csh->detail) {
		MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].vector_index = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
	}
}
Beispiel #3
0
// Shows a ScheduleParam
void Macro_showScheduleParam( ScheduleParam *param, uint8_t analog )
{
	// Analog
	if ( analog )
	{
		printInt8( param->analog );
	}
	// Everything else
	else
	{
		Macro_showScheduleType( param->state );
	}

	// Time
	print(":");
	printInt32( param->time.ms );
	print(".");
	printInt32( param->time.ticks );
}
Beispiel #4
0
void cliFunc_usbInitTime( char* args )
{
	// Calculate overall USB initialization time
	// XXX A protocol analyzer will be more accurate, however, this is built-in and easier to collect data
	print(NL);
	info_msg("USB Init Time: ");
	printInt32( USBInit_TimeEnd - USBInit_TimeStart );
	print(" ms - ");
	printInt16( USBInit_Ticks );
	print(" ticks");
}
Beispiel #5
0
void blockMatch(volatile uint16_t *now, volatile uint16_t *last, int size, int search_radius, int block_size, result_t *result) {
	/* tmp */
	int min, diff;
	int s, x;
	int b = 0;
	int i = 0;
	/* output */
	int aktShift = 0;
	int gshift_a[2*MAX_SEARCH_RADIUS+1] = {0};
	int* gshift = &gshift_a[MAX_SEARCH_RADIUS];

	/* calculate sector shift */
	while (b <= size) {
		aktShift = 0;
		min = INT_MAX;
		for (s = -search_radius; s <= search_radius; ++s) {
			if ((b + s >= 0) && (b + block_size + s <= size)) {
				diff = 0;
				for (x = b; x < b + block_size; ++x) {
					diff += pow(now[x] - last[x + s], 2);
				}
				if (config.s.oflow_algo & DEBUG) {
					printInt32(diff);
					printChar('\t');
				}
				if (diff < min)	{
					min = diff;
					aktShift = s;
				}
				gshift[s] += diff;
			}
		}
		result->vector[i++] = aktShift;
		b += block_size;
	}
	
	/* calculate global shift */	
	min = INT_MAX;
	for (s = -search_radius; s <= search_radius; ++s) {
		if (gshift[s] < min) {
			min = gshift[s];
			aktShift = s;
		}
	}
	
	result->global = aktShift;// / size;
	result->size = size;
}
Beispiel #6
0
// Update external current (mA)
// Triggers power change event
void Output_update_external_current( unsigned int current )
{
	// Only signal if changed
	if ( current == Output_ExtCurrent_Available )
		return;

	// Update external current
	Output_ExtCurrent_Available = current;

	unsigned int total_current = Output_current_available();
	info_msg("External Available Current Changed. Total Available: ");
	printInt32( total_current );
	print(" mA" NL);

	// Send new total current to the Scan Modules
	Scan_currentChange( Output_current_available() );
}
Beispiel #7
0
void cliFunc_ledFPS( char* args )
{
	print( NL ); // No \r\n by default after the command is entered

	char* curArgs;
	char* arg1Ptr;
	char* arg2Ptr = args;

	// Process speed argument if given
	curArgs = arg2Ptr;
	CLI_argumentIsolation( curArgs, &arg1Ptr, &arg2Ptr );

	// Just toggling FPS display
	if ( *arg1Ptr == '\0' )
	{
		info_msg("FPS Toggle");
		LED_displayFPS = !LED_displayFPS;
		return;
	}

	// Check if f argument was given
	switch ( *arg1Ptr )
	{
	case 'r': // Reset framerate
	case 'R':
		LED_framerate = ISSI_FrameRate_ms_define;
		break;

	default: // Convert to a number
		LED_framerate = numToInt( arg1Ptr );
		break;
	}

	// Show result
	info_msg("Setting framerate to: ");
	printInt32( LED_framerate );
	print("ms");
}
Beispiel #8
0
inline void LED_scan()
{
	// Latency measurement start
	Latency_start_time( ledLatencyResource );

	// Check for current change event
	if ( LED_currentEvent )
	{
		// Turn LEDs off in low power mode
		if ( LED_currentEvent < 150 )
		{
			LED_enable_current = 0;

			// Pause animations and clear display
			Pixel_setAnimationControl( AnimationControl_WipePause );
		}
		else
		{
			LED_enable_current = 1;

			// Start animations
			Pixel_setAnimationControl( AnimationControl_Forward );
		}

		LED_currentEvent = 0;
	}

	// Check if an LED_pause is set
	// Some ISSI operations need a clear buffer, but still have the chip running
	if ( LED_pause )
		goto led_finish_scan;

	// Check enable state
	if ( LED_enable && LED_enable_current )
	{
		// Disable Hardware shutdown of ISSI chips (pull high)
		GPIO_Ctrl( hardware_shutdown_pin, GPIO_Type_DriveHigh, GPIO_Config_Pullup );
	}
	// Only write pages to I2C if chip is enabled (i.e. Hardware shutdown is disabled)
	else
	{
		// Enable hardware shutdown
		GPIO_Ctrl( hardware_shutdown_pin, GPIO_Type_DriveLow, GPIO_Config_Pullup );
		goto led_finish_scan;
	}

	// Check if any I2C buses have errored
	// Reset the buses and restart the Frame State
	if ( i2c_error() )
	{
		i2c_reset();
		Pixel_FrameState = FrameState_Update;
	}

	// Only start if we haven't already
	// And if we've finished updating the buffers
	if ( Pixel_FrameState == FrameState_Sending )
		goto led_finish_scan;

	// Only send frame to ISSI chip if buffers are ready
	if ( Pixel_FrameState != FrameState_Ready )
		goto led_finish_scan;

	// Adjust frame rate (i.e. delay and do something else for a bit)
	Time duration = Time_duration( LED_timePrev );
	if ( duration.ms < LED_framerate )
		goto led_finish_scan;

	// FPS Display
	if ( LED_displayFPS )
	{
		// Show frame calculation
		dbug_msg("1frame/");
		printInt32( Time_ms( duration ) );
		print("ms + ");
		printInt32( duration.ticks );
		print(" ticks");

		// Check if we're not meeting frame rate
		if ( duration.ms > LED_framerate )
		{
			print(" - Could not meet framerate: ");
			printInt32( LED_framerate );
		}

		print( NL );
	}

	// Emulated brightness control
	// Lower brightness by LED_brightness
#if ISSI_Chip_31FL3731_define == 1
	for ( uint8_t chip = 0; chip < ISSI_Chips_define; chip++ )
	{
		for ( uint8_t ch = 0; ch < LED_EnableBufferLength; ch++ )
		{
			LED_pageBuffer_brightness[ chip ].ledctrl[ ch ] = LED_pageBuffer[ chip ].ledctrl[ ch ];
		}

		for ( uint8_t ch = 0; ch < LED_BufferLength; ch++ )
		{
			// Don't modify is 0
			if ( LED_pageBuffer[ chip ].buffer[ ch ] == 0 || LED_brightness == 0 )
			{
				LED_pageBuffer_brightness[ chip ].buffer[ ch ] = 0;
				continue;
			}

			// XXX (HaaTa) Yes, this is a bit slow, but it's pretty accurate
			LED_pageBuffer_brightness[ chip ].buffer[ ch ] =
				(LED_pageBuffer[ chip ].buffer[ ch ] * LED_brightness) / 0xFF;
		}
	}
#endif

	// Update frame start time
	LED_timePrev = Time_now();

	// Set the page of all the ISSI chips
	// This way we can easily link the buffers to send the brightnesses in the background
	for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
	{
		uint8_t bus = LED_ChannelMapping[ ch ].bus;
		// Page Setup
		LED_setupPage(
			bus,
			LED_ChannelMapping[ ch ].addr,
			ISSI_LEDPwmPage
		);
	}

	// Send current set of buffers
	// Uses interrupts to send to all the ISSI chips
	// Pixel_FrameState will be updated when complete
	LED_chipSend = 0; // Start with chip 0
	LED_linkedSend();

led_finish_scan:
	// Latency measurement end
	Latency_end_time( ledLatencyResource );
}
Beispiel #9
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 );
			}

		}
	}
Beispiel #10
0
int32_t i2c_send_sequence(
	uint8_t ch,
	uint16_t *sequence,
	uint32_t sequence_length,
	uint8_t *received_data,
	void ( *callback_fn )( void* ),
	void *user_data
) {
	int32_t result = 0;

	volatile I2C_Channel *channel = &( i2c_channels[ch - ISSI_I2C_FirstBus_define] );
	uint8_t address;

#if defined(_kinetis_)
	uint8_t status;
	volatile uint8_t *I2C_C1  = (uint8_t*)(&I2C0_C1) + i2c_offset[ch];
	volatile uint8_t *I2C_S   = (uint8_t*)(&I2C0_S) + i2c_offset[ch];
	volatile uint8_t *I2C_D   = (uint8_t*)(&I2C0_D) + i2c_offset[ch];
#elif defined(_sam_)
	Twi *twi_dev = twi_devs[ch];
#endif

	if ( channel->status == I2C_BUSY )
	{
		return -1;
	}

	// Check if there are back-to-back errors
	// in succession
	if ( channel->last_error > 5 )
	{
		warn_msg("I2C Bus Error: ");
		printInt8( ch );
		print(" errors: ");
		printInt32( channel->error_count );
		print( NL );
	}

	// Debug
	/*
	for ( uint8_t c = 0; c < sequence_length; c++ )
	{
		printHex( sequence[c] );
		print(" ");
	}
	print(NL);
	*/

	channel->sequence = sequence;
	channel->sequence_end = sequence + sequence_length;
	channel->received_data = received_data;
	channel->status = I2C_BUSY;
	channel->txrx = I2C_WRITING;
	channel->callback_fn = callback_fn;
	channel->user_data = user_data;

	// reads_ahead does not need to be initialized

#if defined(_kinetis_)
	// Acknowledge the interrupt request, just in case
	*I2C_S |= I2C_S_IICIF;
	*I2C_C1 = ( I2C_C1_IICEN | I2C_C1_IICIE );

	// Generate a start condition and prepare for transmitting.
	*I2C_C1 |= ( I2C_C1_MST | I2C_C1_TX );

	status = *I2C_S;
	if ( status & I2C_S_ARBL )
	{
		warn_print("Arbitration lost");
		result = -1;
		goto i2c_send_sequence_cleanup;
	}

	// Write the first (address) byte.
	address = *channel->sequence++;
	*I2C_D = address;

	// Everything is OK.
	return result;

i2c_send_sequence_cleanup:
	// Record error, and reset last error counter
	channel->error_count++;
	channel->last_error++;

	// Generate STOP and disable further interrupts.
	*I2C_C1 &= ~( I2C_C1_IICIE | I2C_C1_MST | I2C_C1_TX );
	channel->status = I2C_ERROR;

#elif defined(_sam_)
	// Convert 8 bit address to 7bit + RW
	address = *channel->sequence++;
	//print("Address: ");
	//printHex( address );
	//print( NL );

	uint8_t mread = address & 1;
	address >>= 1;

	// Set slave address
	twi_dev->TWI_MMR = TWI_MMR_DADR(address) | (mread ? TWI_MMR_MREAD : 0);

	// Enable interrupts
	twi_dev->TWI_IER = TWI_IER_RXRDY | TWI_IER_TXRDY | TWI_IER_TXCOMP | TWI_IER_ARBLST;
	//twi_dev->TWI_IDR = 0xFFFFFFFF;

	// Generate a start condition
	twi_dev->TWI_CR |= TWI_CR_START;

	// Fire off the first read or write.
	// The first (address) byte is automatically trasmitted before any data
	// Arbitration errors will be handled in the isr
	i2c_isr(ch);

	// Everything is OK.
	return result;
#endif

	return result;
}
Beispiel #11
0
inline void LED_scan()
{
	// Latency measurement start
	Latency_start_time( ledLatencyResource );

	// Check for current change event
	if ( LED_currentEvent )
	{
		// Turn LEDs off in low power mode
		if ( LED_currentEvent < 150 )
		{
			LED_enable = 0;

			// Pause animations and clear display
			Pixel_setAnimationControl( AnimationControl_WipePause );
		}
		else
		{
			LED_enable = 1;

			// Start animations
			Pixel_setAnimationControl( AnimationControl_Forward );
		}

		LED_currentEvent = 0;
	}

	// Check if an LED_pause is set
	// Some ISSI operations need a clear buffer, but still have the chip running
	if ( LED_pause )
		goto led_finish_scan;

	// Check enable state
	if ( LED_enable )
	{
		// Disable Hardware shutdown of ISSI chips (pull high)
		GPIOB_PSOR |= (1<<16);
	}
	// Only write pages to I2C if chip is enabled (i.e. Hardware shutdown is disabled)
	else
	{
		// Enable hardware shutdown
		GPIOB_PCOR |= (1<<16);
		goto led_finish_scan;
	}

	// Only start if we haven't already
	// And if we've finished updating the buffers
	if ( Pixel_FrameState == FrameState_Sending )
		goto led_finish_scan;

	// Only send frame to ISSI chip if buffers are ready
	if ( Pixel_FrameState != FrameState_Ready )
		goto led_finish_scan;

	// Adjust frame rate (i.e. delay and do something else for a bit)
	Time duration = Time_duration( LED_timePrev );
	if ( duration.ms < LED_framerate )
		goto led_finish_scan;

	// FPS Display
	if ( LED_displayFPS )
	{
		// Show frame calculation
		dbug_msg("1frame/");
		printInt32( Time_ms( duration ) );
		print("ms + ");
		printInt32( duration.ticks );
		print(" ticks");

		// Check if we're not meeting frame rate
		if ( duration.ms > LED_framerate )
		{
			print(" - Could not meet framerate: ");
			printInt32( LED_framerate );
		}

		print( NL );
	}

	// Emulated brightness control
	// Lower brightness by LED_brightness
#if ISSI_Chip_31FL3731_define == 1
	uint8_t inverse_brightness = 0xFF - LED_brightness;
	for ( uint8_t chip = 0; chip < ISSI_Chips_define; chip++ )
	{
		for ( uint8_t ch = 0; ch < LED_BufferLength; ch++ )
		{
			// Don't modify is 0
			if ( LED_pageBuffer[ chip ].buffer[ ch ] == 0 )
			{
				LED_pageBuffer_brightness[ chip ].buffer[ ch ] = 0;
				continue;
			}

			LED_pageBuffer_brightness[ chip ].buffer[ ch ] =
				LED_pageBuffer[ chip ].buffer[ ch ] - inverse_brightness < 0
				? 0x0
				: LED_pageBuffer[ chip ].buffer[ ch ] - inverse_brightness;
		}
	}
#endif

	// Update frame start time
	LED_timePrev = Time_now();

	// Set the page of all the ISSI chips
	// This way we can easily link the buffers to send the brightnesses in the background
	for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
	{
		uint8_t bus = LED_ChannelMapping[ ch ].bus;
		// Page Setup
		LED_setupPage(
			bus,
			LED_ChannelMapping[ ch ].addr,
			ISSI_LEDPwmPage
		);

#if ISSI_Chip_31FL3731_define == 1 || ISSI_Chip_31FL3732_define == 1
		// Reset LED enable mask
		// XXX At high speeds, the IS31FL3732 seems to have random bit flips
		//     To get around this, just re-set the enable mask before each send
		// XXX Might be sufficient to do this every N frames though
		while ( i2c_send( bus, (uint16_t*)&LED_ledEnableMask[ ch ], sizeof( LED_EnableBuffer ) / 2 ) == -1 )
			delay_us( ISSI_SendDelay );
#endif
	}

	// Send current set of buffers
	// Uses interrupts to send to all the ISSI chips
	// Pixel_FrameState will be updated when complete
	LED_chipSend = 0; // Start with chip 0
	LED_linkedSend();

led_finish_scan:
	// Latency measurement end
	Latency_end_time( ledLatencyResource );
}