void nrf_ll_init( void ) { // GPIO configuration nrf_ll_ce_low(); nrf_ll_csn_high(); platform_pio_op( NRF24L01_CE_PORT, 1 << NRF24L01_CE_PIN, PLATFORM_IO_PIN_DIR_OUTPUT ); platform_pio_op( NRF24L01_CSN_PORT, 1 << NRF24L01_CSN_PIN, PLATFORM_IO_PIN_DIR_OUTPUT ); platform_pio_op( NRF24L01_IRQ_PORT, 1 << NRF24L01_IRQ_PIN, PLATFORM_IO_PIN_DIR_INPUT ); // UART configuration is already done in platform.c // Empty UART buffer while( platform_uart_recv( NRF24L01_UART_ID, 0, 0 ) != -1 ); }
static void all_exti_irqhandler( int line ) { u16 v, port, pin; v = exti_line_to_gpio( line ); port = PLATFORM_IO_GET_PORT( v ); pin = PLATFORM_IO_GET_PIN( v ); if( EXTI->RTSR & (1 << line ) && platform_pio_op( port, 1 << pin, PLATFORM_IO_PIN_GET ) ) cmn_int_handler( INT_GPIO_POSEDGE, v ); if( EXTI->FTSR & (1 << line ) && ( platform_pio_op( port, 1 << pin, PLATFORM_IO_PIN_GET ) == 0 ) ) cmn_int_handler( INT_GPIO_NEGEDGE, v ); EXTI_ClearITPendingBit( exti_line[ line ] ); }
// Helper function: pin operations // Gets the stack index of the first pin and the operation static int pioh_set_pins( lua_State* L, int stackidx, int op ) { int total = lua_gettop( L ); int i, v, port, pin; pioh_clear_masks(); // Get all masks for( i = stackidx; i <= total; i ++ ) { v = luaL_checkinteger( L, i ); port = PLATFORM_IO_GET_PORT( v ); pin = PLATFORM_IO_GET_PIN( v ); if( PLATFORM_IO_IS_PORT( v ) || !platform_pio_has_port( port ) || !platform_pio_has_pin( port, pin ) ) return luaL_error( L, "invalid pin" ); pio_masks[ port ] |= 1 << pin; } // Ask platform to execute the given operation for( i = 0; i < PLATFORM_IO_PORTS; i ++ ) if( pio_masks[ i ] ) if( !platform_pio_op( i, pio_masks[ i ], op ) ) return luaL_error( L, "invalid PIO operation" ); return 0; }
// Lua: val1, val2, ..., valn = pio.port.getval( port1, port2, ..., portn ) static int pio_port_getval( lua_State *L ) { pio_type value; int v, i, port; int total = lua_gettop( L ); for( i = 1; i <= total; i ++ ) { v = luaL_checkinteger( L, i ); port = PLATFORM_IO_GET_PORT( v ); if( !PLATFORM_IO_IS_PORT( v ) || !platform_pio_has_port( port ) ) return luaL_error( L, "invalid port" ); else { value = platform_pio_op( port, PLATFORM_IO_ALL_PINS, PLATFORM_IO_PORT_GET_VALUE ); lua_pushinteger( L, value ); } } return total; }
void ps2_init() { // Setup pins (inputs with external pullups) platform_pio_op( PS2_DATA_PORT, 1 << PS2_DATA_PIN, PLATFORM_IO_PIN_DIR_INPUT ); platform_pio_op( PS2_CLOCK_PORT, 1 << PS2_CLOCK_PIN, PLATFORM_IO_PIN_DIR_INPUT ); platform_pio_op( PS2_RESET_PORT, 1 << PS2_RESET_PIN, PLATFORM_IO_PIN_DIR_INPUT ); platform_pio_op( PS2_DATA_PORT, 1 << PS2_DATA_PIN, PLATFORM_IO_PIN_CLEAR ); platform_pio_op( PS2_CLOCK_PORT, 1 << PS2_CLOCK_PIN, PLATFORM_IO_PIN_CLEAR ); platform_pio_op( PS2_RESET_PORT, 1 << PS2_RESET_PIN, PLATFORM_IO_PIN_CLEAR ); // Enable interrupt on clock line ps2_prev_handler = elua_int_set_c_handler( INT_GPIO_NEGEDGE, ps2_hl_clk_int_handler ); platform_cpu_set_interrupt( INT_GPIO_NEGEDGE, PS2_CLOCK_PIN_RESNUM, PLATFORM_CPU_ENABLE ); // Reset + typematic rate ps2_send( 3, PS2_CMD_RESET, 2, PS2_CMD_TYPE_RATE, 1, 0x00, 1 ); }
// Lua: pin1, pin2, ..., pinn = pio.pin.getval( pin1, pin2, ..., pinn ) static int pio_pin_getval( lua_State *L ) { pio_type value; int v, i, port, pin; int total = lua_gettop( L ); for( i = 1; i <= total; i ++ ) { v = luaL_checkinteger( L, i ); port = PLATFORM_IO_GET_PORT( v ); pin = PLATFORM_IO_GET_PIN( v ); if( PLATFORM_IO_IS_PORT( v ) || !platform_pio_has_port( port ) || !platform_pio_has_pin( port, pin ) ) return luaL_error( L, "invalid pin" ); else { value = platform_pio_op( port, 1 << pin, PLATFORM_IO_PIN_GET ); lua_pushinteger( L, value ); } } return total; }
// Helper function: port operations // Gets the stack index of the first port and the operation (also the mask) static int pioh_set_ports( lua_State* L, int stackidx, int op, pio_type mask ) { int total = lua_gettop( L ); int i, v, port; u32 port_mask = 0; // Get all masks for( i = stackidx; i <= total; i ++ ) { v = luaL_checkinteger( L, i ); port = PLATFORM_IO_GET_PORT( v ); if( !PLATFORM_IO_IS_PORT( v ) || !platform_pio_has_port( port ) ) return luaL_error( L, "invalid port" ); port_mask |= ( 1ULL << port ); } // Ask platform to execute the given operation for( i = 0; i < PLATFORM_IO_PORTS; i ++ ) if( port_mask & ( 1ULL << i ) ) if( !platform_pio_op( i, mask, op ) ) return luaL_error( L, "invalid PIO operation" ); return 0; }
void initMAC( const u8* bytMacAddress ) { pdata = bytMacAddress; // Initialize the SPI and the CS pin theclock = platform_spi_setup( ENC28J60_SPI_ID, PLATFORM_SPI_MASTER, ENC28J60_SPI_CLOCK, 0, 0, 8 ); platform_pio_op( ENC28J60_CS_PORT, 1 << ENC28J60_CS_PIN, PLATFORM_IO_PIN_SET ); platform_pio_op( ENC28J60_CS_PORT, 1 << ENC28J60_CS_PIN, PLATFORM_IO_PIN_DIR_OUTPUT ); #if defined( ENC28J60_RESET_PORT ) && defined( ENC28J60_RESET_PIN ) platform_pio_op( ENC28J60_RESET_PORT, 1 << ENC28J60_RESET_PIN, PLATFORM_IO_PIN_CLEAR ); platform_pio_op( ENC28J60_RESET_PORT, 1 << ENC28J60_RESET_PIN, PLATFORM_IO_PIN_DIR_OUTPUT ); platform_timer_delay( 0, 30000 ); platform_pio_op( ENC28J60_RESET_PORT, 1 << ENC28J60_RESET_PIN, PLATFORM_IO_PIN_SET ); #endif ResetMac(); // erm. Resets the MAC. // setup memory by defining ERXST and ERXND platform_timer_delay( 0, 20000 ); BankSel(0); // select bank 0 WriteCtrReg(ERXSTL,(u08)( RXSTART & 0x00ff)); WriteCtrReg(ERXSTH,(u08)((RXSTART & 0xff00)>> 8)); WriteCtrReg(ERXNDL,(u08)( RXEND & 0x00ff)); WriteCtrReg(ERXNDH,(u08)((RXEND & 0xff00)>>8)); // Make sure Rx Read ptr is at the start of Rx segment WriteCtrReg(ERXRDPTL, (u08)( RXSTART & 0x00ff)); WriteCtrReg(ERXRDPTH, (u08)((RXSTART & 0xff00)>> 8)); BankSel(1); // select bank 1 WriteCtrReg(ERXFCON,( ERXFCON_UCEN + ERXFCON_CRCEN + ERXFCON_BCEN)); // Initialise the MAC registers BankSel(2); // select bank 2 SetBitField(MACON1, MACON1_MARXEN); // Enable reception of frames WriteCtrReg(MACLCON2, 63); WriteCtrReg(MACON3, MACON3_FRMLNEN + // Type / len field will be checked MACON3_TXCRCEN + // MAC will append valid CRC MACON3_PADCFG0); // All small packets will be padded SetBitField(MACON4, MACON4_DEFER); WriteCtrReg(MAMXFLL, (u08)( MAXFRAMELEN & 0x00ff)); // set max frame len WriteCtrReg(MAMXFLH, (u08)((MAXFRAMELEN & 0xff00)>>8)); WriteCtrReg(MABBIPG, 0x12); // back to back interpacket gap. set as per data sheet WriteCtrReg(MAIPGL , 0x12); // non back to back interpacket gap. set as per data sheet WriteCtrReg(MAIPGH , 0x0C); //Program our MAC address BankSel(3); WriteCtrReg(MAADR1,bytMacAddress[0]); WriteCtrReg(MAADR2,bytMacAddress[1]); WriteCtrReg(MAADR3,bytMacAddress[2]); WriteCtrReg(MAADR4,bytMacAddress[3]); WriteCtrReg(MAADR5,bytMacAddress[4]); WriteCtrReg(MAADR6,bytMacAddress[5]); // Initialise the PHY registes WritePhyReg(PHCON1, 0x00); WritePhyReg(PHCON2, PHCON2_HDLDIS); WriteCtrReg(ECON1, ECON1_RXEN); //Enable the chip for reception of packets SetBitField(EIE, EIE_INTIE); WritePhyReg(PHIE, PHIE_PGEIE|PHIE_PLNKIE); ReadPhyReg(PHIR); }
int nrf_ll_get_irq( void ) { return platform_pio_op( NRF24L01_IRQ_PORT, 1 << NRF24L01_IRQ_PIN, PLATFORM_IO_PIN_GET ); }
void nrf_ll_set_csn( int state ) { platform_pio_op( NRF24L01_CSN_PORT, 1 << NRF24L01_CSN_PIN, state == 1 ? PLATFORM_IO_PIN_SET : PLATFORM_IO_PIN_CLEAR ); }
// H->L clock line interrupt handler static void ps2_hl_clk_int_handler( elua_int_resnum resnum ) { int temp; unsigned i; if( resnum != PS2_CLOCK_PIN_RESNUM ) goto done; ps2_bitcnt ++; if( ps2_bitcnt != 1 && ps2_bitcnt < 10 ) // start/stop/parity bits, ignore ps2_data |= platform_pio_op( PS2_DATA_PORT, 1 << PS2_DATA_PIN, PLATFORM_IO_PIN_GET ) << ( ps2_bitcnt - 2 ); else if( ps2_bitcnt == 11 ) // done receiving, the code is in ps2_data now { /// Check the "send" part first if( ps2_acks_to_receive > 0 ) { ps2_data = ps2_bitcnt = 0; if( -- ps2_acks_to_receive == 0 ) { if( -- ps2_cmds_to_send != 0 ) // more data to send? ps2h_send_cmd( ++ ps2_send_idx ); } goto done; } else // nothing is sending, so interpret this code { if( ps2_ignore_count > 0 ) // need to ignore this code? ps2_ignore_count --; else { if( ps2_is_set( PS2_IF_EXTENDED ) ) // extended key management { if( ps2_is_set( PS2_IF_BREAK ) ) // code of extended key that was released { if( ps2_data == PS2_CTRL_CODE ) // CTRL released { ps2_clear_flag( PS2_IF_EXT_CTRL ); if( !ps2_is_set( PS2_IF_CTRL ) ) ps2_clear_flag( PS2_CTRL ); } else if( ps2_data == PS2_ALT_CODE ) // ALT released { ps2_clear_flag( PS2_IF_EXT_ALT ); if( !ps2_is_set( PS2_IF_ALT ) ) ps2_clear_flag( PS2_ALT ); } ps2_clear_flag( PS2_IF_BREAK ); ps2_clear_flag( PS2_IF_EXTENDED ); } else if( ps2_data == PS2_BREAK_CODE ) ps2_set_flag( PS2_IF_BREAK ); else { if( ps2_data == PS2_CTRL_CODE ) ps2_set_flag( PS2_IF_EXT_CTRL | PS2_CTRL ); if( ps2_data == PS2_ALT_CODE ) ps2_set_flag( PS2_IF_EXT_ALT | PS2_ALT ); else // Map keycode, add to queue if needed for( i = 0; i < sizeof( ps2_ext_mapping ) / sizeof( ps2_keymap ); i ++ ) if( ps2_ext_mapping[ i ].kc == ps2_data ) { // Check for CTRL+ATL+DEL if( ps2_ext_mapping[ i ].code == KC_DEL && ps2_is_set( PS2_ALT ) && ps2_is_set( PS2_CTRL ) ) { ps2h_reset(); while( 1 ); // obviously we won't reach code after this } ps2_queue[ ps2_w_idx ] = ( ( ps2_flags & PS2_BASEF_MASK ) << PS2_BASEF_SHIFT ) | ps2_ext_mapping[ i ].code; ps2_w_idx = ( ps2_w_idx + 1 ) & PS2_QUEUE_MASK; break; } ps2_clear_flag( PS2_IF_EXTENDED ); } } // end of extended key management else if( ps2_is_set( PS2_IF_BREAK ) ) // code of key that was released { if( ps2_data == PS2_CTRL_CODE ) // CTRL released { ps2_clear_flag( PS2_IF_CTRL ); if( !ps2_is_set( PS2_IF_EXT_CTRL ) ) ps2_clear_flag( PS2_CTRL ); } else if( ps2_data == PS2_ALT_CODE ) // ALT released { ps2_clear_flag( PS2_IF_ALT ); if( !ps2_is_set( PS2_IF_EXT_ALT ) ) ps2_clear_flag( PS2_ALT ); } else if( ps2_data == PS2_LSHIFT_CODE ) { ps2_clear_flag( PS2_IF_LSHIFT ); if( !ps2_is_set( PS2_IF_RSHIFT ) ) ps2_clear_flag( PS2_SHIFT ); } else if( ps2_data == PS2_RSHIFT_CODE ) { ps2_clear_flag( PS2_IF_RSHIFT ); if( !ps2_is_set( PS2_IF_LSHIFT ) ) ps2_clear_flag( PS2_SHIFT ); } else if( ps2_data == PS2_CAPS_CODE ) { if( ps2_is_set( PS2_IF_CAPS ) ) { ps2_clear_flag( PS2_IF_CAPS ); ps2_send( 2, PS2_CMD_LED_SET, 1, 0, 1 ); } else { ps2_set_flag( PS2_IF_CAPS ); ps2_send( 2, PS2_CMD_LED_SET, 1, PS2_CAPS_LED_MASK, 1 ); } } ps2_clear_flag( PS2_IF_BREAK ); } else if( ps2_data == PS2_PAUSE_1ST_CODE ) // ignore everything related to this crazy key ps2_ignore_count = PS2_PAUSE_NUM_CODES - 1; else if( ps2_data == PS2_EXTENDED_CODE ) // this is an extended key ps2_set_flag( PS2_IF_EXTENDED ); else if( ps2_data == PS2_BREAK_CODE ) // found a break ps2_set_flag( PS2_IF_BREAK ); else if( ps2_data == PS2_CTRL_CODE ) // CTRL pressed ps2_set_flag( PS2_IF_CTRL | PS2_CTRL ); else if( ps2_data == PS2_ALT_CODE ) // ALT pressed ps2_set_flag( PS2_IF_ALT | PS2_ALT ); else if( ps2_data == PS2_LSHIFT_CODE ) // Left SHIFT pressed ps2_set_flag( PS2_IF_LSHIFT | PS2_SHIFT ); else if( ps2_data == PS2_RSHIFT_CODE ) // Right SHIFT pressed ps2_set_flag( PS2_IF_RSHIFT | PS2_SHIFT ); else { // Check if we need to enqueue a key if( ps2_data == PS2_F7_CODE ) // special case to keep mapping arrays small temp = KC_F7; else if( ps2_data > PS2_LAST_MAP_CODE ) temp = 0; else if( ps2_is_set( PS2_SHIFT ) ) temp = ps2_shift_mapping[ ps2_data ]; else temp = ps2_direct_mapping[ ps2_data ]; if( temp ) { if( ps2_is_set( PS2_IF_CAPS ) && isalpha( temp ) ) temp = toupper( temp ); ps2_queue[ ps2_w_idx ] = ( ( ps2_flags & PS2_BASEF_MASK ) << PS2_BASEF_SHIFT ) | temp; ps2_w_idx = ( ps2_w_idx + 1 ) & PS2_QUEUE_MASK; } } } } ps2_data = ps2_bitcnt = 0; } done: if( ps2_prev_handler ) ps2_prev_handler( resnum ); }