int led_ioctl(const device_cfg_t * cfg, int request, void * ctl){ led_req_t * req = ctl; pio_t port_pin; pio_attr_t req_attr; if( request == I_LED_SET ){ if ( req->channel > 3 ){ errno = EINVAL; return -1; } port_pin = cfg->pcfg.pio[req->channel]; if ( req->on != 0 ){ req_attr.mask = (1<<port_pin.pin); req_attr.mode = PIO_MODE_OUTPUT; hwpl_pio_setattr(port_pin.port, &req_attr); if ( cfg->pin_assign == LED_ACTIVE_LOW ){ hwpl_pio_clrmask(port_pin.port, (void*)(1<<port_pin.pin)); } else { hwpl_pio_setmask(port_pin.port, (void*)(1<<port_pin.pin)); } } else { req_attr.mask = (1<<port_pin.pin); req_attr.mode = PIO_MODE_INPUT; hwpl_pio_setattr(port_pin.port, &req_attr); if ( cfg->pin_assign == LED_ACTIVE_LOW ){ hwpl_pio_setmask(port_pin.port, (void*)(1<<port_pin.pin)); } else { hwpl_pio_clrmask(port_pin.port, (void*)(1<<port_pin.pin)); } } } return 0; }
void led_priv_off(void * args){ uint32_t * pinmask = (uint32_t *)args; pio_attr_t attr; attr.mask = (*pinmask); hwpl_pio_clrmask(1, (void*)(attr.mask)); attr.mode = PIO_MODE_INPUT; hwpl_pio_setattr(1, &attr); }
void sst25vf_share_assert_cs(const device_cfg_t * cfg){ hwpl_pio_clrmask(cfg->pcfg.spi.cs.port, (void*)(ssize_t)(1<<cfg->pcfg.spi.cs.pin)); }
static void assert_cs(void){ hwpl_pio_clrmask(LCD_SPI_CS_PORT, (void*)LCD_SPI_CS_PINMASK); //assert SPI delay(); }
static void command_mode(void){ hwpl_pio_clrmask(LCD_SPI_A0_PORT, (void*)LCD_SPI_A0_PINMASK); //enter command mode delay(); }
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; }