Exemple #1
0
void Nhdc12832::refresh(void){
	Spi spi(spi_port);
	uint8_t buffer[MEM_ROWS];
	unsigned int i,j;
	unsigned char page = 0xB0;			//Page Address + 0xB0
	//cmd_out(0xAE);					//Display OFF
	cmd_out(0x40);					//Display start address + 0x40
	for(i=0;i<MEM_COLUMNS;i++){				//32pixel display / 8 pixels per page = 4 pages
		assert_cmd();
		buffer[0] = page;	//send page address
		buffer[1] = 0x10;	//column address upper 4 bits + 0x10
		buffer[2] = 0x00;	//column address lower 4 bits + 0x00
		assert_cs();
		spi.write(buffer, 3);
		deassert_cs();
		for(j=0;j<MEM_ROWS;j++){			//128 rows wide
			buffer[j] = nhd_mem[j][i];
		}
		assert_data();
		assert_cs();
		spi.write(buffer, MEM_ROWS);
		deassert_cs();
		page++;					//after 128 columns, go to next page
	}
	cmd_out(0xAF);					//Display ON
}
Exemple #2
0
void Nhdc12832::cmd_out(unsigned char c){
	Spi spi(spi_port);
	assert_cmd();
	assert_cs();
	spi.swap(c);
	deassert_cs();
}
Exemple #3
0
int lcd_usecond_match_event(void * context, const void * data){

	//If an application is holding the LCD -- don't update
	if( lcd_hold == 0x80 ){
		LCD_REFRESHED(); //clear the touched bit

		lcd_page = 0xB0;
		lcd_write_state = LCD_WRITE_PAGE;
		lcd_buffer[0] = 0x40;

		op.callback = lcd_spi_complete_event;
		op.context = context;
		op.nbyte = 1;
		op.buf = lcd_buffer;
		op.tid = 0;
		op.loc = 0;
		op.flags = 0;

		if( hwpl_spi_write(context, &op) < 0 ){
			deassert_cs();
		}

	} else {
		update_count(); //interrupt again on next timer match
	}

	return 1; //keep interrupt in place
}
Exemple #4
0
void Nhdc12832::cmd_out(const void * cmd, int nbyte){
	Spi spi(spi_port);
	int i;
	const unsigned char * p = (const unsigned char*)cmd;
	assert_cmd();
	for(i=0; i < nbyte; i++){
		assert_cs();
		spi.swap(*p++);
		deassert_cs();
	}
}
Exemple #5
0
void Nhdc12832::data_out(const void * data, int nbyte){
	Spi spi(spi_port);
	int i;
	const char * p = (const char*)data;
	assert_data();
	for(i=0; i < nbyte; i++){
		assert_cs();
		spi.swap(*p++);
		deassert_cs();
	}
}
Exemple #6
0
static int jlink_spi_send_command(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
		const unsigned char *writearr, unsigned char *readarr)
{
	uint32_t length;
	uint8_t *buffer;

	length = writecnt + readcnt;

	if (length > JTAG_MAX_TRANSFER_SIZE)
		return SPI_INVALID_LENGTH;

	buffer = malloc(length);

	if (!buffer) {
		msg_perr("Memory allocation failed.\n");
		return SPI_GENERIC_ERROR;
	}

	/* Reverse all bytes because the device transfers data LSB first. */
	reverse_bytes(buffer, writearr, writecnt);

	memset(buffer + writecnt, 0x00, readcnt);

	if (!assert_cs()) {
		free(buffer);
		return SPI_PROGRAMMER_ERROR;
	}

	int ret;

	ret = jaylink_jtag_io(jaylink_devh, buffer, buffer, buffer, length * 8, JAYLINK_JTAG_VERSION_2);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_jag_io() failed: %s.\n", jaylink_strerror(ret));
		free(buffer);
		return SPI_PROGRAMMER_ERROR;
	}

	if (!deassert_cs()) {
		free(buffer);
		return SPI_PROGRAMMER_ERROR;
	}

	/* Reverse all bytes because the device transfers data LSB first. */
	reverse_bytes(readarr, buffer + writecnt, readcnt);
	free(buffer);

	return 0;
}
Exemple #7
0
int lcd_spi_complete_event(void * context, const void * data){
	int j;
	int i;

	//deassert CS each time a SPI event completes
	deassert_cs();

	i = lcd_page - 0xB0;
	if( i == LCD_COLS ){
		lcd_hold = 0x00;
		update_count(); //interrupt again on next timer match
		return 0; //all done
	}

	switch(lcd_write_state){
	case LCD_WRITE_PAGE:

		command_mode();
		lcd_buffer[0] = lcd_page;
		lcd_buffer[1] = 0x10;
		lcd_buffer[2] = 0x00;

		op.nbyte = 3;

		assert_cs();

		lcd_write_state = LCD_WRITE_DATA;
		hwpl_spi_write(context, &op);
		return 1;
	case LCD_WRITE_DATA:

		data_mode();
		assert_cs();

		for(j=0;j<LCD_ROWS;j++){			//128 rows high
			lcd_buffer[j] = mem[LCD_ROWS - j - 1][i];
		}

		op.nbyte = LCD_ROWS;

		lcd_page++;
		lcd_write_state = LCD_WRITE_PAGE;
		hwpl_spi_write(context, &op);
		break;
	}

	return 1;
}
Exemple #8
0
int jlink_spi_init(void)
{
	char *arg;
	unsigned long speed = 0;

	register_shutdown(jlink_spi_shutdown, NULL);

	arg = extract_programmer_param("spispeed");

	if (arg) {
		char *endptr;

		errno = 0;
		speed = strtoul(arg, &endptr, 10);

		if (*endptr != '\0' || errno != 0) {
			msg_perr("Invalid SPI speed specified: %s.\n", arg);
			free(arg);
			return 1;
		}

		if (speed < 1) {
			msg_perr("SPI speed must be at least 1 kHz.\n");
			free(arg);
			return 1;
		}
	}

	free(arg);

	int ret;
	bool use_serial_number;
	uint32_t serial_number;

	arg = extract_programmer_param("serial");

	if (arg) {
		if (!strlen(arg)) {
			msg_perr("Emptpy serial number specified.\n");
			free(arg);
			return 1;
		}

		ret = jaylink_parse_serial_number(arg, &serial_number);

		if (ret == JAYLINK_ERR) {
			msg_perr("Invalid serial number specified: %s.\n", arg);
			free(arg);
			return 1;
		} if (ret != JAYLINK_OK) {
			msg_perr("jaylink_parse_serial_number() failed: %s.\n", jaylink_strerror(ret));
			free(arg);
			return 1;
		}

		use_serial_number = true;
	} else {
		use_serial_number = false;
	}

	free(arg);

	reset_cs = true;
	arg = extract_programmer_param("cs");

	if (arg) {
		if (!strcasecmp(arg, "reset")) {
			reset_cs = true;
		} else if (!strcasecmp(arg, "trst")) {
			reset_cs = false;
		} else {
			msg_perr("Invalid chip select pin specified: '%s'.\n", arg);
			free(arg);
			return 1;
		}
	}

	free(arg);

	if (reset_cs)
		msg_pdbg("Using RESET as chip select signal.\n");
	else
		msg_pdbg("Using TRST as chip select signal.\n");

	ret = jaylink_init(&jaylink_ctx);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_init() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	ret = jaylink_discovery_scan(jaylink_ctx, 0);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_discover_scan() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	struct jaylink_device **devs;

	ret = jaylink_get_devices(jaylink_ctx, &devs, NULL);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_get_devices() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	if (!use_serial_number)
		msg_pdbg("No device selected, using first device.\n");

	size_t i;
	struct jaylink_device *dev;
	bool device_found = false;

	for (i = 0; devs[i]; i++) {
		if (use_serial_number) {
			uint32_t tmp;

			ret = jaylink_device_get_serial_number(devs[i], &tmp);

			if (ret == JAYLINK_ERR_NOT_AVAILABLE) {
				continue;
			} else if (ret != JAYLINK_OK) {
				msg_pwarn("jaylink_device_get_serial_number() failed: %s.\n",
					jaylink_strerror(ret));
				continue;
			}

			if (serial_number != tmp)
				continue;
		}

		ret = jaylink_open(devs[i], &jaylink_devh);

		if (ret == JAYLINK_OK) {
			dev = devs[i];
			device_found = true;
			break;
		}

		jaylink_devh = NULL;
	}

	jaylink_free_devices(devs, true);

	if (!device_found) {
		msg_perr("No J-Link device found.\n");
		return 1;
	}

	size_t length;
	char *firmware_version;

	ret = jaylink_get_firmware_version(jaylink_devh, &firmware_version,
		&length);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_get_firmware_version() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	} else if (length > 0) {
		msg_pdbg("Firmware: %s\n", firmware_version);
		free(firmware_version);
	}

	ret = jaylink_device_get_serial_number(dev, &serial_number);

	if (ret == JAYLINK_OK) {
		msg_pdbg("S/N: %" PRIu32 "\n", serial_number);
	} else if (ret == JAYLINK_ERR_NOT_AVAILABLE) {
		msg_pdbg("S/N: N/A\n");
	} else {
		msg_perr("jaylink_device_get_serial_number() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	uint8_t caps[JAYLINK_DEV_EXT_CAPS_SIZE];

	memset(caps, 0, sizeof(caps));
	ret = jaylink_get_caps(jaylink_devh, caps);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_get_caps() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_EXT_CAPS)) {
		ret = jaylink_get_extended_caps(jaylink_devh, caps);

		if (ret != JAYLINK_OK) {
			msg_perr("jaylink_get_available_interfaces() failed: %s.\n", jaylink_strerror(ret));
			return 1;
		}
	}

	uint32_t ifaces;

	ret = jaylink_get_available_interfaces(jaylink_devh, &ifaces);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_get_available_interfaces() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	if (!(ifaces & (1 << JAYLINK_TIF_JTAG))) {
		msg_perr("Device does not support JTAG interface.\n");
		return 1;
	}

	ret = jaylink_select_interface(jaylink_devh, JAYLINK_TIF_JTAG, NULL);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_select_interface() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	struct jaylink_hardware_status hwstat;

	ret = jaylink_get_hardware_status(jaylink_devh, &hwstat);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_get_hardware_status() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	msg_pdbg("VTarget: %u.%03u V\n", hwstat.target_voltage / 1000,
		hwstat.target_voltage % 1000);

	if (hwstat.target_voltage < MIN_TARGET_VOLTAGE) {
		msg_perr("Target voltage is below %u.%03u V. You need to attach VTref to the I/O voltage of "
			"the chip.\n", MIN_TARGET_VOLTAGE / 1000, MIN_TARGET_VOLTAGE % 1000);
		return 1;
	}

	struct jaylink_speed device_speeds;

	device_speeds.freq = DEFAULT_FREQ;
	device_speeds.div = DEFAULT_FREQ_DIV;

	if (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_SPEEDS)) {
		ret = jaylink_get_speeds(jaylink_devh, &device_speeds);

		if (ret != JAYLINK_OK) {
			msg_perr("jaylink_get_speeds() failed: %s.\n", jaylink_strerror(ret));
			return 1;
		}
	}

	device_speeds.freq /= 1000;

	msg_pdbg("Maximum SPI speed: %" PRIu32 " kHz\n", device_speeds.freq / device_speeds.div);

	if (!speed) {
		speed = device_speeds.freq / device_speeds.div;
		msg_pdbg("SPI speed not specified, using %lu kHz.\n", speed);
	}

	if (speed > (device_speeds.freq / device_speeds.div)) {
		msg_perr("Specified SPI speed of %lu kHz is too high. Maximum is %" PRIu32 " kHz.\n", speed,
			device_speeds.freq / device_speeds.div);
		return 1;
	}

	ret = jaylink_set_speed(jaylink_devh, speed);

	if (ret != JAYLINK_OK) {
		msg_perr("jaylink_set_speed() failed: %s.\n", jaylink_strerror(ret));
		return 1;
	}

	msg_pdbg("SPI speed: %lu kHz\n", speed);

	/* Ensure that the CS signal is not active initially. */
	if (!deassert_cs())
		return 1;

	register_spi_master(&spi_master_jlink_spi);

	return 0;
}
Exemple #9
0
int lcd_ioctl(const device_cfg_t * cfg, int request, void * ctl){
	mlcd_attr_t * attr = (mlcd_attr_t*)ctl;
	tmr_action_t action;
	pio_attr_t pattr;
	device_periph_t p;

	switch(request){
	case I_MLCD_GETATTR:
		attr->freq = LCD_FREQ; //LCD updates 30 times per second
		attr->h = LCD_HEIGHT;
		attr->w = LCD_WIDTH;
		attr->size = LCD_ROWS * LCD_COLS;
		attr->mem = mem;
		attr->hold = lcd_hold;
		attr->rows = LCD_ROWS;
		attr->cols = LCD_COLS/4;
		attr->orientation = (ORIENT_BOTTOM)|(ORIENT_LEFT);
		break;

	case I_MLCD_CLEAR:
		memset(mem, 0, LCD_ROWS * LCD_COLS);
		lcd_hold = 0x80;
		break;

	case I_MLCD_HOLD:
		if( LCD_HOLD_COUNT() < 127 ){
			lcd_hold++;
		}
		break;

	case I_MLCD_RELEASE:
		if( LCD_HOLD_COUNT() > 0 ){
			lcd_hold--;
			LCD_TOUCH();
		}
		break;

	case I_MLCD_INIT:

		//initialize the IO -- chip select first
		pattr.mask = LCD_SPI_CS_PINMASK;
		pattr.mode = PIO_MODE_OUTPUT;
		p.port = LCD_SPI_CS_PORT;
		hwpl_pio_open((device_cfg_t*)&p);
		hwpl_pio_setattr(LCD_SPI_CS_PORT, &pattr);
		hwpl_pio_setmask(LCD_SPI_CS_PORT, (void*)LCD_SPI_CS_PINMASK);

		//Now A0
		pattr.mask = LCD_SPI_A0_PINMASK;
		if( p.port != LCD_SPI_A0_PORT ){
			p.port = LCD_SPI_A0_PORT;
			hwpl_pio_open((device_cfg_t*)&p);
		}
		hwpl_pio_setattr(LCD_SPI_A0_PORT, &pattr);
		hwpl_pio_setmask(LCD_SPI_A0_PORT, (void*)LCD_SPI_A0_PINMASK);

		//configure the timer to update the LCD
		action.channel = LCD_USECOND_OC;
		action.event = TMR_ACTION_EVENT_INTERRUPT;
		action.callback = lcd_usecond_match_event;
		action.context = (void*)cfg;
		hwpl_tmr_setaction(LCD_USECOND_TMR, &action);

		const char start[] = {0xA0, 0xAE, 0xC0, 0xA2, 0x2F, 0x21, 0x81, 0x2F};
		int i;
		const char * p = (const char*)start;

		command_mode();
		hwpl_pio_clrmask(LCD_SPI_A0_PORT, (void*)LCD_SPI_A0_PINMASK); //enter command mode

		for(i=0; i < 8; i++){
			assert_cs();
			hwpl_spi_swap(LCD_SPI_PORT, (void*)(uint32_t)(*p++));
			deassert_cs();
		}

		//start the timer update to refresh the screen
		update_count();
		break;

	case I_MLCD_ON:
		command_mode();
		assert_cs();
		hwpl_spi_swap(LCD_SPI_PORT, (void*)0xAF);
		deassert_cs();
		break;

	case I_MLCD_OFF:
		command_mode();
		assert_cs();
		hwpl_spi_swap(LCD_SPI_PORT, (void*)0xAE);
		deassert_cs();
		break;

	default:
		errno = EINVAL;
		return -1;
	}


	return 0;
}