track ctrl

This commit is contained in:
kraus 2018-03-30 20:40:27 +02:00
parent 5076054488
commit 21a66684fb
3 changed files with 435 additions and 9 deletions

View File

@ -35,6 +35,8 @@
#include <Arduino.h>
#include <U8g2lib.h>
#include <string.h>
#include <stdarg.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
@ -43,6 +45,9 @@
#include <Wire.h>
#endif
#define MENU_FONT u8g2_font_helvB18_tr
/*
158*128
bold: 65..70
@ -103,20 +108,116 @@ const uint8_t track_font[1646] U8G2_FONT_SECTION("track_font") =
"j*\246r\242h\251\6\23\0\0\0\0";
/*================================================================================*/
U8G2_ST75256_JLX256128_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 7, /* dc=*/ 6, /* reset=*/ 5); // MKR Zero, Enable U8g2 16 bit mode for this display
/*================================================================================*/
uint8_t test_i2c_address(uint8_t adr)
{
Wire.beginTransmission(adr);
return Wire.endTransmission(false);
}
void system_test(void)
{
u8x8_SetFont(u8g2.getU8x8(), u8x8_font_amstrad_cpc_extended_r);
u8x8_Draw1x2String(u8g2.getU8x8(), 0, 0, "Oli's Spur N Controller (2018)");
u8x8_DrawString(u8g2.getU8x8(), 0, 3, "Teste I2C Weichen...");
if ( test_i2c_address(17) == 0 )
u8x8_DrawString(u8g2.getU8x8(), 26, 3, "Ok");
else
u8x8_DrawString(u8g2.getU8x8(), 26, 3, "Fehler");
u8x8_DrawString(u8g2.getU8x8(), 0, 4, "Teste I2C Motortreiber...");
if ( test_i2c_address(40) == 0 )
u8x8_DrawString(u8g2.getU8x8(), 26, 4, "Ok");
else
u8x8_DrawString(u8g2.getU8x8(), 26, 4, "Fehler");
/* wait for keypress */
while( u8g2.getMenuEvent() == 0 )
;
}
void setup(void) {
// MKR Zero Test Board
u8g2.begin(/*Select=*/ 0, /*Right/Next=*/ 1, /*Left/Prev=*/ 2, /*Up=*/ 4, /*Down=*/ 3, /*Home/Cancel=*/ A5);
u8g2.begin(/*Select=*/ 0, /*Right/Next=*/ 1, /*Left/Prev=*/ 2, /*Up=*/ 4, /*Down=*/ 3, /*Home/Cancel=*/ A6);
u8g2.setFontMode(1);
Wire.begin();
system_test();
}
/*================================================================================*/
#define LOG_BUF_LINES 7
#define LOG_BUF_LINE_LEN 32
#define LOG_FONT u8g2_font_lucasfont_alternate_tr
#define LOG_FONT_LH 9
char log_buf[LOG_BUF_LINES][LOG_BUF_LINE_LEN];
uint8_t log_end = 0;
//u8g2_font_u8glib_4_tr
void draw_log(void)
{
uint8_t i;
u8g2.setFont(LOG_FONT);
for( i = 0; i < LOG_BUF_LINES; i++ )
{
u8g2.drawStr(160, 64+i*LOG_FONT_LH, log_buf[i]);
}
}
void scroll_log(void)
{
uint8_t i;
for( i = 1; i < LOG_BUF_LINES; i++ )
{
strcpy(log_buf[i-1], log_buf[i]);
}
log_buf[LOG_BUF_LINES-1][0] = '\0';
}
void log_line(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vsnprintf(log_buf[log_end], LOG_BUF_LINE_LEN, fmt, va);
log_buf[log_end][LOG_BUF_LINE_LEN-1] = '\0';
va_end(va);
if ( log_end < LOG_BUF_LINES-1 )
{
log_end++;
}
else
{
scroll_log();
}
}
/*================================================================================*/
struct menu_entry_type
{
const uint8_t *font;
@ -146,8 +247,8 @@ struct menu_state
struct menu_entry_type menu_entry_list[] =
{
{ u8g2_font_open_iconic_other_8x_t, 66, "Weichen-Test"},
{ u8g2_font_open_iconic_embedded_8x_t, 67, "Motor Test"},
{ u8g2_font_open_iconic_embedded_8x_t, 66, "Gear Game"},
{ u8g2_font_open_iconic_embedded_8x_t, 67, "Flash Light"},
{ u8g2_font_open_iconic_embedded_8x_t, 68, "Home"},
{ u8g2_font_open_iconic_embedded_8x_t, 72, "Configuration"},
{ NULL, 0, NULL }
@ -268,7 +369,7 @@ uint16_t main_menu(void)
do
{
main_menu_draw(&current_state);
u8g2.setFont(u8g2_font_helvB18_tr);
u8g2.setFont(MENU_FONT);
u8g2.setCursor((u8g2.getDisplayWidth()-u8g2.getStrWidth(menu_entry_list[destination_state.position].name))/2,u8g2.getDisplayHeight()-7);
u8g2.print(menu_entry_list[destination_state.position].name);
check_button_event();
@ -301,9 +402,23 @@ int16_t track_switch_y[4][2] = { { 0, 16 }, { 55, 55 }, { 104, 114 }, { 114,
/* sw=0..3, pos=0..1 */
void set_swtich(uint8_t sw, uint8_t pos)
{
uint8_t error;
sw &= 3;
pos &= 1;
Wire.beginTransmission(17); // switch controller
Wire.write(0);
Wire.write(sw*2+pos);
error = Wire.endTransmission(false);
if ( error == 0 )
{
Wire.beginTransmission(17); // switch controller
Wire.write(0);
Wire.write(sw*2+pos);
Wire.endTransmission();
log_line("I2C ok %d, sw=%d/%d", error, sw, pos);
}
else
{
log_line("I2C err %d, sw=%d/%d", error, sw, pos);
}
}
@ -354,6 +469,8 @@ void show_tracks(void)
check_button_event();
draw_log();
} while( u8g2.nextPage() );
}
@ -363,6 +480,7 @@ void track_switch_test(void)
{
track_bold1_idx = -1;
track_bold2_idx = -1;
button_event = 0;
for(;;)
{
show_tracks();
@ -386,17 +504,119 @@ void track_switch_test(void)
track_switch[2] ^=1;
set_swtich(2, track_switch[2]);
}
if ( button_event == U8X8_MSG_GPIO_MENU_HOME )
return;
button_event = 0;
}
}
/*================================================================================*/
/* sw=0..3, pos=0..1 */
void set_motor_speed(uint8_t motor, uint8_t speed)
{
uint8_t error;
Wire.beginTransmission(40+motor); // motor controller
error = Wire.endTransmission(false);
if ( error == 0 )
{
Wire.beginTransmission(40+motor); // switch controller
Wire.write(0);
Wire.write(speed);
Wire.endTransmission();
log_line("I2C ok %d, m%d/%d", error, motor, speed);
}
else
{
log_line("I2C err %d, m%d/%d", error, motor, speed);
}
}
void show_motor_set_speed(uint8_t motor, uint8_t speed)
{
u8g2_uint_t y;
u8g2_uint_t o = 18;
button_event = 0;
u8g2.firstPage();
do
{
check_button_event();
u8g2.setFont(MENU_FONT);
u8g2.drawBox(5, 0, 2, 128);
u8g2.drawHLine(0, 127-speed/2, 12);
check_button_event();
y = (uint8_t)(((uint16_t)(128-o)*(uint16_t)(127-speed/2))>>7);
u8g2.setCursor(16, y+o);
u8g2.print(speed);
check_button_event();
u8g2.setCursor(70, 20);
u8g2.print("Motor: ");
u8g2.print(motor);
draw_log();
} while( u8g2.nextPage() );
}
void motor_speed_test(void)
{
uint8_t speed[6] = { 0, 0, 0, 0, 0, 0 };
uint8_t step = 10;
uint8_t motor = 0;
for( motor = 0; motor < 6; motor++)
set_motor_speed(motor, speed[motor]);
motor = 0;
for(;;)
{
show_motor_set_speed(motor, speed[motor]);
if ( button_event == U8X8_MSG_GPIO_MENU_UP )
{
if ( speed[motor] < 255-step )
speed[motor] += step;
else
speed[motor] = 255;
set_motor_speed(motor, speed[motor]);
}
if ( button_event == U8X8_MSG_GPIO_MENU_DOWN )
{
if ( speed[motor] >= step )
speed[motor] -=step;
else
speed[motor] = 0;
set_motor_speed(motor, speed[motor]);
}
if ( button_event == U8X8_MSG_GPIO_MENU_SELECT )
{
motor++;
if ( motor >= 6 )
motor = 0;
set_motor_speed(motor, speed[motor]);
}
if ( button_event == U8X8_MSG_GPIO_MENU_HOME )
{
button_event = 0;
return;
}
button_event = 0;
}
}
/*================================================================================*/
void loop(void)
{
uint16_t pos;
pos = main_menu();
track_switch_test();
if ( pos == 0 )
track_switch_test();
else if ( pos == 1 )
motor_speed_test();
}

View File

@ -34,7 +34,7 @@ GCCBINPATH:=/usr/bin/
# Project Information
# The name for the project
TARGETNAME:=si9986_scope
TARGETNAME:=drv8871
# The source files of the project
CSRC:=$(wildcard *.c)

View File

@ -1067,11 +1067,216 @@ void __attribute__ ((interrupt, used)) TIM22_IRQHandler(void)
TIM22->SR &= ~TIM_SR_UIF; /* clear interrupt */
}
/*=======================================================================*/
/* I2C */
volatile unsigned char i2c_mem[256]; /* contains data, which read or written */
volatile unsigned char i2c_idx; /* the current index into i2c_mem */
volatile unsigned char i2c_is_write_idx; /* write state */
volatile uint16_t i2c_total_irq_cnt;
volatile uint16_t i2c_TXIS_cnt;
volatile uint16_t i2c_RXNE_cnt;
void i2c_mem_reset_write(void)
{
i2c_is_write_idx = 1;
}
void i2c_mem_init(void)
{
i2c_idx = 0;
i2c_mem_reset_write();
}
void i2c_mem_set_index(unsigned char value)
{
i2c_idx = value;
i2c_is_write_idx = 0;
}
void i2c_mem_write_via_index(unsigned char value)
{
if ( i2c_idx == 0 )
{
/* additionall put this byte into the queue */
//addCmdToGPIOQueue(value);
}
i2c_mem[i2c_idx++] = value;
}
unsigned char i2c_mem_read(void)
{
i2c_mem_reset_write();
i2c_idx++;
return i2c_mem[i2c_idx];
}
void i2c_mem_write(unsigned char value)
{
if ( i2c_is_write_idx != 0 )
{
i2c_mem_set_index(value);
}
else
{
i2c_is_write_idx = 0;
i2c_mem_write_via_index(value);
}
}
/* address: I2C address multiplied by 2 */
/* Pins PA9 (SCL) and PA10 (SDA) */
void i2c_hw_init(unsigned char address)
{
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; /* Enable clock for I2C */
RCC->IOPENR |= RCC_IOPENR_IOPAEN; /* Enable clock for GPIO Port A */
__NOP(); /* extra delay for clock stabilization required? */
__NOP();
/* configure io */
GPIOA->MODER &= ~GPIO_MODER_MODE9; /* clear mode for PA9 */
GPIOA->MODER |= GPIO_MODER_MODE9_1; /* alt fn */
GPIOA->OTYPER |= GPIO_OTYPER_OT_9; /* open drain */
GPIOA->AFR[1] &= ~(15<<4); /* Clear Alternate Function PA9 */
GPIOA->AFR[1] |= 1<<4; /* I2C Alternate Function PA9 */
GPIOA->MODER &= ~GPIO_MODER_MODE10; /* clear mode for PA10 */
GPIOA->MODER |= GPIO_MODER_MODE10_1; /* alt fn */
GPIOA->OTYPER |= GPIO_OTYPER_OT_10; /* open drain */
GPIOA->AFR[1] &= ~(15<<8); /* Clear Alternate Function PA10 */
GPIOA->AFR[1] |= 1<<8; /* I2C Alternate Function PA10 */
RCC->CCIPR &= ~RCC_CCIPR_I2C1SEL; /* write 00 to the I2C clk selection register */
RCC->CCIPR |= RCC_CCIPR_I2C1SEL_0; /* select system clock (01) */
/* I2C init flow chart: Clear PE bit */
I2C1->CR1 &= ~I2C_CR1_PE;
/* I2C init flow chart: Configure filter */
/* leave at defaults */
/* I2C init flow chart: Configure timing */
/*
standard mode 100kHz configuration
SYSCLK = I2CCLK = 32 MHz
PRESC = 6 bits 28..31
SCLL = 0x13 bits 0..7
SCLH = 0x0f bits 8..15
SDADEL = 0x02 bits 16..19
SCLDEL = 0x04 bits 20..23
*/
I2C1->TIMINGR = 0x60420f13;
/* I2C init flow chart: Configure NOSTRECH */
I2C1->CR1 |= I2C_CR1_NOSTRETCH;
/* I2C init flow chart: Enable I2C */
I2C1->CR1 |= I2C_CR1_PE;
/* disable OAR1 for reconfiguration */
I2C1->OAR1 &= ~I2C_OAR1_OA1EN;
I2C1->OAR1 = address;
I2C1->OAR1 |= I2C_OAR1_OA1EN;
/* enable interrupts */
I2C1->CR1 |= I2C_CR1_STOPIE;
I2C1->CR1 |= I2C_CR1_NACKIE;
//I2C1->CR1 |= I2C_CR1_ADDRIE;
I2C1->CR1 |= I2C_CR1_RXIE;
I2C1->CR1 |= I2C_CR1_TXIE;
/* load first value into TXDR register */
I2C1->TXDR = i2c_mem[i2c_idx];
/* enable IRQ in NVIC */
NVIC_SetPriority(I2C1_IRQn, 0);
NVIC_EnableIRQ(I2C1_IRQn);
}
void i2c_init(unsigned char address)
{
i2c_mem_init();
i2c_hw_init(address);
}
void __attribute__ ((interrupt, used)) I2C1_IRQHandler(void)
{
unsigned long isr = I2C1->ISR;
i2c_total_irq_cnt ++;
if ( isr & I2C_ISR_TXIS )
{
i2c_TXIS_cnt++;
I2C1->TXDR = i2c_mem_read();
}
else if ( isr & I2C_ISR_RXNE )
{
i2c_RXNE_cnt++;
i2c_mem_write(I2C1->RXDR);
I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
I2C1->TXDR = i2c_mem[i2c_idx];
}
else if ( isr & I2C_ISR_STOPF )
{
I2C1->ICR = I2C_ICR_STOPCF;
I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
I2C1->TXDR = i2c_mem[i2c_idx];
i2c_mem_reset_write();
}
else if ( isr & I2C_ISR_NACKF )
{
I2C1->ICR = I2C_ICR_NACKCF;
I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
I2C1->TXDR = i2c_mem[i2c_idx];
i2c_mem_reset_write();
}
else if ( isr & I2C_ISR_ADDR )
{
/* not required, the addr match interrupt is not enabled */
I2C1->ICR = I2C_ICR_ADDRCF;
I2C1->ISR |= I2C_ISR_TXE; // allow overwriting the TCDR with new data
I2C1->TXDR = i2c_mem[i2c_idx];
i2c_mem_reset_write();
}
/* if at any time the addr match is set, clear the flag */
/* not sure, whether this is required */
if ( isr & I2C_ISR_ADDR )
{
I2C1->ICR = I2C_ICR_ADDRCF;
}
}
/*=======================================================================*/
void main()
int main()
{
uint16_t adc_value;
uint16_t tim_duty;
@ -1081,6 +1286,7 @@ void main()
setHSIClock(); /* enable 32 MHz Clock */
startUp(); /* enable systick irq and several power regions */
i2c_hw_init(40*2); /* activage I2C, adr = 40 */
initDisplay(); /* aktivate display */
initADC();
@ -1195,5 +1401,5 @@ void main()
u8g2_SendBuffer(&u8g2);
}
return 0;
}