X-Git-Url: http://git.kpe.io/?p=avr_bc100.git;a=blobdiff_plain;f=BaseMegaFirmware%2FGCC%2Fport_ext.c;fp=BaseMegaFirmware%2FGCC%2Fport_ext.c;h=40ff4ab274bfa51b4b59db17df30298f162c9090;hp=0000000000000000000000000000000000000000;hb=89173ec9cd6f33843bf27c45be0f2f9be3f5f0ce;hpb=7997f136b12114035265bd082c854bff95fd73dc diff --git a/BaseMegaFirmware/GCC/port_ext.c b/BaseMegaFirmware/GCC/port_ext.c new file mode 100644 index 0000000..40ff4ab --- /dev/null +++ b/BaseMegaFirmware/GCC/port_ext.c @@ -0,0 +1,126 @@ +// Martin Thomas 4/2008 + +#include +#include +#include +#include "port_ext.h" + +// #include "mystdio.h" + +static uint8_t virtports[PORT_EXT_OUTPORTS] = { + PORT_EXT_INIT0, + PORT_EXT_INIT1, + PORT_EXT_INIT2 +}; + +static inline void strobe_delay(void) +{ +#if 0 + // delay ca. 100ns @ 2V for 74x595, 1us for tests + _delay_us(1); +#else + // 1 cycle ca 130ns at 7,3MHz + asm volatile("nop"::); +#endif +} + +static inline void output_disable(void) +{ + PORT_EXT_PORT |= ( 1 << PORT_EXT_PIN_OE ); +} + +static inline void output_enable(void) +{ + PORT_EXT_PORT &= ~( 1 << PORT_EXT_PIN_OE ); +} + +static inline void pulse_latch(void) +{ + PORT_EXT_PORT |= ( 1 << PORT_EXT_PIN_LATCH ); + strobe_delay(); + PORT_EXT_PORT &= ~( 1 << PORT_EXT_PIN_LATCH ); + strobe_delay(); +} + +static inline void pulse_clock(void) +{ + PORT_EXT_PORT |= ( 1 << PORT_EXT_PIN_CLK ); + strobe_delay(); + PORT_EXT_PORT &= ~( 1 << PORT_EXT_PIN_CLK ); + strobe_delay(); +} + +static void shift_out(void) +{ + uint8_t i, bit; + + // first bit shifted out is bit7 in virtports[PORT_EXT_OUTPORTS-1] + // - on BC100 this is for U205 Q7 + // last bit shifted out is bit 0 in virtports[0] + // - on BC100 this is for U202 Q0 + for ( i = PORT_EXT_OUTPORTS; i > 0; i-- ) { + // myprintf_P("Port %d = %d\n", i-1, virtports[i-1] ); + for ( bit = 8; bit > 0; bit-- ) { + if ( virtports[i-1] & ( 1 << (bit-1) ) ) { + PORT_EXT_PORT |= ( 1 << PORT_EXT_PIN_DIN ); + } + else { + PORT_EXT_PORT &= ~( 1 << PORT_EXT_PIN_DIN ); + } + pulse_clock(); + } + } + pulse_latch(); +} + +void port_ext_init(void) +{ + PORT_EXT_PORT &= ~( + ( 1 << PORT_EXT_PIN_CLK ) | + ( 1 << PORT_EXT_PIN_DIN) | + ( 1 << PORT_EXT_PIN_LATCH ) ); + PORT_EXT_PORT |= ( 1 << PORT_EXT_PIN_OE ); + PORT_EXT_DDR |= ( + ( 1 << PORT_EXT_PIN_OE) | + ( 1 << PORT_EXT_PIN_CLK ) | + ( 1 << PORT_EXT_PIN_DIN) | + ( 1 << PORT_EXT_PIN_LATCH ) ); + // set inititial values before enabling outputs + // - on BC100 this is just for U202 since it's + // the only 74x595 with switchable /OE + shift_out(); + output_enable(); + // since Q7' is low while output is disabled (low) + // (Philips 74HC(T)595 datasheet) another shift- + // out has to be done to set the cascaded outputs + // - on BC100 this will set U201, U202 and U205 outputs + shift_out(); +} + +void port_ext_update(void) +{ + shift_out(); +} + +void port_ext_bit_clear( uint8_t port, uint8_t bit ) +{ + if ( ( port < PORT_EXT_OUTPORTS ) && ( bit < 8 ) ) { + virtports[port] &= ~( 1 << bit ); + } +} + +void port_ext_bit_set( uint8_t port, uint8_t bit ) +{ + if ( ( port < PORT_EXT_OUTPORTS ) && ( bit < 8 ) ) { + virtports[port] |= ( 1 << bit ); + } +} + +void port_ext_set( uint8_t port, uint8_t val ) +{ + if ( port < PORT_EXT_OUTPORTS ) { + virtports[port] = val; + } +} + +