void shift_clock(unsigned char * SFR)//Provides clock for the shift module (shift register clock) { _SFR_IO8(*(SFR+2))|=(1<<(*(SFR+3)));//Rising Edge #if ((SHIFT_CLOCK_DELAY)!=0) _delay_ms(SHIFT_CLOCK_DELAY); #endif _SFR_IO8(*(SFR+2))&=~(1<<(*(SFR+3)));//Falling Edge }
void shift_latch_data(unsigned char * SFR)//Used to latch data in the shift module { _SFR_IO8(*(SFR+4))|=(1<<(*(SFR+5)));//Rising Edge #if ((SHIFT_LATCH_DELAY)!=0) _delay_ms(SHIFT_LATCH_DELAY); #endif _SFR_IO8(*(SFR+4))&=~(1<<(*(SFR+5)));//Falling Edge }
void shift_data_out_bit(unsigned char data,unsigned char * SFR)//Shift module output bit stream function { if(data) { _SFR_IO8(*(SFR)) |=(1<<(*(SFR+1))); } else { _SFR_IO8(*(SFR)) &=~(1<<(*(SFR+1))); } }
unsigned char shift_data_in_bit(unsigned char * SFR)//Shift module input bit stream function { if(_SFR_IO8(*(SFR)) & (1<<(*(SFR+1)))) return 1; else return 0; }
int main(void) { _SFR_IO8(0x17) |= 1 << PINB3; // DDRB Set pin 3 to output (*(volatile uint8_t *)((0x17) + 0x20)) &= ~(1 << PINB4); // DDRB Set pin 4 to input (*(volatile uint8_t *)((0x18) + 0x20)) |= 1 << PINB4; // PORTB Set pin 4 to high while(1) { // _SFR_IO8(0x18) and // (*(volatile uint8_t *)((0x18) + 0x20)) and // (*(volatile unsigned char *)((0x18) + 0x20)) are equivalent (*(volatile unsigned char *)((0x18) + 0x20)) ^= 1 << PINB3; // Toggle pin 3 (LED) // Test whether bit PINB4 in IO register PINB is clear (Low). // This will return TRUE if the bit is clear, and a FALSE if the bit is set (High). if(bit_is_clear(PINB, PINB4)) { _delay_ms(100); // While the button is pressed (Button short-circuits PINB4 to the ground) } else { _delay_ms(500); // While the button is not pressed (PINB4 is set high) } } }
static void output(uint8_t val) { #ifndef AVR printf("%d\n", val); #else _SFR_IO8(OUTPORT) = val; #endif }
void servoService(void) { u16 nextTics; if(ServoChannel < SERVO_NUM_CHANNELS) { // turn off current channel outb(_SFR_IO8(ServoChannels[ServoChannel].port), inb(_SFR_IO8(ServoChannels[ServoChannel].port)) & ~(ServoChannels[ServoChannel].pin)); } // next channel ServoChannel++; if(ServoChannel != SERVO_NUM_CHANNELS) { // loop to channel 0 if needed if(ServoChannel > SERVO_NUM_CHANNELS) ServoChannel = 0; // turn on new channel outb(_SFR_IO8(ServoChannels[ServoChannel].port), inb(_SFR_IO8(ServoChannels[ServoChannel].port)) | (ServoChannels[ServoChannel].pin)); // schedule turn off time nextTics = ServoChannels[ServoChannel].duty; } else //(Channel == SERVO_NUM_CHANNELS) { // ***we could save time by precalculating this // schedule end-of-period nextTics = ServoPeriodTics-ServoPosTics; } // schedule next interrupt u16 OCValue; // read in current value of output compare register OCR1A OCValue = inb(OCR1AL); // read low byte of OCR1A OCValue += inb(OCR1AH)<<8; // read high byte of OCR1A // increment OCR1A value by nextTics OCValue += nextTics; // OCR1A+=nextTics; // set future output compare time to this new value outb(OCR1AH, (OCValue>>8)); // write high byte outb(OCR1AL, (OCValue & 0x00FF)); // write low byte // set our new tic position ServoPosTics += nextTics; if(ServoPosTics >= ServoPeriodTics) ServoPosTics = 0; }
void cmdGetPort(uint8_t argc, char** argv) { if(argc == 2) { unsigned char addr = getint(&argv[1]); unsigned char val = _SFR_IO8(addr); printf_P(PSTR("%d=%d\n"), (int)addr, (int)val); } //else //printf("err: GP addr\n"); }
void doRead(char** argv, char argc) { if(argc == 2) { unsigned char addr = strtoint(argv[1]); unsigned char val = _SFR_IO8(addr); printf("%d=%d\n", (int)addr, (int)val); } else printf("err: addr\n"); }
void cmdSetPort(uint8_t argc, char** argv) { if(argc == 3) { unsigned char addr = getint(&argv[1]); unsigned char val = getint(&argv[2]); _SFR_IO8(addr) = val; printf_P(PSTR("OK\n")); } //else //printf("err: SP addr value\n"); }
void doWrite(char** argv, char argc) { if(argc == 3) { unsigned char addr = strtoint(argv[1]); unsigned char val = strtoint(argv[2]); _SFR_IO8(addr) = val; printf("OK\n"); } else printf("err: addr value\n"); }
//--------------------------------------------------------------------------- static void Thread_Switch(void) { #if KERNEL_USE_IDLE_FUNC // If there's no next-thread-to-run... if (g_pstNext == Kernel_GetIdleThread()) { g_pstCurrent = Kernel_GetIdleThread(); // Disable the SWI, and re-enable interrupts -- enter nested interrupt // mode. KernelSWI_DI(); K_UCHAR ucSR = _SFR_IO8(SR_); // So long as there's no "next-to-run" thread, keep executing the Idle // function to conclusion... while (g_pstNext == Kernel_GetIdleThread()) { // Ensure that we run this block in an interrupt enabled context (but // with the rest of the checks being performed in an interrupt disabled // context). ASM( "sei" ); Kernel_IdleFunc(); ASM( "cli" ); } // Progress has been achieved -- an interrupt-triggered event has caused // the scheduler to run, and choose a new thread. Since we've already // saved the context of the thread we've hijacked to run idle, we can // proceed to disable the nested interrupt context and switch to the // new thread. _SFR_IO8(SR_) = ucSR; KernelSWI_RI( true ); } #endif g_pstCurrent = (Thread_t*)g_pstNext; }
void _output_setup() { for (uint8_t i=0; i<_output_index; i++) { //DDR _SFR_IO8(getSFR(i) + _DDR) |= 1<<getBit(i); //state if (getState(i) == 0) { setLo(i); } else { setHi(i); } } }
void writeRegister() const { const uint8_t ioreg = this->_u8RegNr; const uint8_t value = this->_u8RegValue; _SFR_IO8(ioreg) = value; }
static inline void disable_pullups(uint8_t mask) { _SFR_IO8(port_adr) &= ~mask; }
static inline uint8_t read() { return _SFR_IO8(in_adr); }
void shiftDmxOut(int pin, int theByte) { int port_to_output[] = { NOT_A_PORT, NOT_A_PORT, _SFR_IO_ADDR(PORTB), _SFR_IO_ADDR(PORTC), _SFR_IO_ADDR(PORTD) }; int portNumber = port_to_output[digitalPinToPort(pin)]; int pinMask = digitalPinToBitMask(pin); // the first thing we do is to write te pin to high // it will be the mark between bytes. It may be also // high from before _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask; delayMicroseconds(10); // disable interrupts, otherwise the timer 0 overflow interrupt that // tracks milliseconds will make us delay longer than we want. cli(); // DMX starts with a start-bit that must always be zero _SFR_BYTE(_SFR_IO8(portNumber)) &= ~pinMask; // we need a delay of 4us (then one bit is transfered) // this seems more stable then using delayMicroseconds asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); for (int i = 0; i < 8; i++) { if (theByte & 01) { _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask; } else { _SFR_BYTE(_SFR_IO8(portNumber)) &= ~pinMask; } asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); theByte >>= 1; } // the last thing we do is to write the pin to high // it will be the mark between bytes. (this break is have to be between 8 us and 1 sec) _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask; // reenable interrupts. sei(); }
static inline void enable_pullups(uint8_t mask) { _SFR_IO8(port_adr) |= mask; }