Stargate switch v2

From Electriki
Revision as of 12:10, 17 April 2011 by Domen (talk | contribs) (stargate switch v2, minus the description)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Work in progress, don't bother reading

Description

TODO

Generic IR sensor with demodulator, ie. TSOP1738, SFH5110

Schematic

Stargate switch v2.png

Code

<syntaxhighlight lang="c">

  1. include <types.h>
  2. include <compiler.h>
  3. include <gpio.h>
  4. include <interrupt.h>
  5. include <mach/lpc13xx_gpio.h>
  6. include <mach/lpc13xx_regs.h>
  7. include <board.h>
  8. include <string.h>
  9. include <stdio.h>

/* timer irq must get called every 889us, pwm has 26.316us duty cycle */

  1. define MODULATION_FREQ 38000
  2. define PULSE_LEN 889


struct lpc13xx_tmr { volatile u32 IR; /* 0x0 */ volatile u32 TCR; /* 0x4 */ volatile u32 TC; /* 0x8 */ volatile u32 PR; /* 0xc */

volatile u32 PC; /* 0x10 */ volatile u32 MCR; /* 0x14 */ volatile u32 MR0; /* 0x18 */ volatile u32 MR1; /* 0x1c */

volatile u32 MR2; /* 0x20 */ volatile u32 MR3; /* 0x24 */ volatile u32 CCR; /* 0x28 */ volatile const u32 CR0; /* 0x2c */ u32 _reserved0[3]; volatile u32 EMR; /* 0x3c */ u32 _reserved1[12]; volatile u32 CTCR; /* 0x70 */ volatile u32 PWMC; /* 0x74 */ };

  1. define TMR16B0_ADDR 0x4000c000
  2. define TMR16B1_ADDR 0x40010000
  3. define TMR32B0_ADDR 0x40014000
  4. define TMR33B1_ADDR 0x40018000


struct sequence { int len; int pos; /* these are MSb first */ u8 tx[4]; u8 rx[4]; };


static struct sequence _seq; static struct sequence *seq = &_seq;

static struct lpc13xx_tmr *t1 = (void*)TMR16B0_ADDR; static struct lpc13xx_tmr *pwm = (void*)TMR16B1_ADDR;

  1. define SENSOR_PIN GPIO_2_1
  2. define LED_PIN GPIO_2_8

void __interrupt timer16_0_irqhandler(void) { int pos = seq->pos; int bit = gpio_get(SENSOR_PIN);

/* clear interrupts */ t1->IR = t1->IR;

/* sensor output is reversed */ if (!bit) seq->rx[pos/8] |= 1 << (7-pos%8); else seq->rx[pos/8] &= ~(1 << (7-pos%8));

pos++; seq->pos = pos;

/* stop */ if (pos == seq->len) { pwm->TCR = 0x0; pwm->TC = 0; /* this turns the led off */ t1->TCR = 0x0; return; }

if (seq->tx[pos/8] & (1 << (7-pos%8))) { pwm->TCR = 0x1; } else { pwm->TCR = 0x0; pwm->TC = 0; /* this turns the led off */ } }


static void setup_timers(void) { LPC_SYSCON->SYSAHBCLKCTRL |= SYSAHBCLKCTRL_CT16B0; LPC_SYSCON->SYSAHBCLKCTRL |= SYSAHBCLKCTRL_CT16B1;

gpio_init(SENSOR_PIN, GPIO_INPUT, 0); LPC_IOCON->PIO1_9 = 1; /* CT16B1_MAT0 */

/* reset */ pwm->TCR = 0x2; pwm->TCR = 0x0;

pwm->PR = 0; pwm->MR0 = (CONFIG_FCPU + MODULATION_FREQ) / (MODULATION_FREQ*2); //pwm->MR3 = (CONFIG_FCPU + MODULATION_FREQ/2) / MODULATION_FREQ; pwm->MR3 = pwm->MR0*2; pwm->MCR = 2<<(3*3); /* reset on MR3 match */ pwm->PWMC = 1<<0; /* PWM on MAT0 */


t1->TCR = 0x2; t1->TCR = 0;

t1->PR = 0; t1->MR0 = CONFIG_FCPU/1000000 * PULSE_LEN; /* with 72 MHz this goes just under 64k */ t1->MCR = 3<<(3*0); /* reset and interrupt on MR0 match */

irq_enable(IRQ_TIMER_16_0); }

/* RC5: 110 11101 (lighting) 000000; 0 is 889us 1, 889us 0; 1 is 889us 0, 889us 1 */ /* this translates to 01011001 01011001 10101010 1010____ */ static const u8 cmd[] = { 0x59, 0x59, 0xaa, 0xa0 };

static void start_timers(void) { seq->len = 14*2; seq->pos = 0; memcpy(seq->tx, cmd, 4);

/* enable if 1 */ if (seq->tx[0] & (1 << 7)) pwm->TCR = 0x1;

/* start the timer */ t1->TCR = 0x1; }

int main() { setup_timers(); gpio_init(LED_PIN, GPIO_OUTPUT, 0);

while (1) { start_timers(); udelay(14*2*1000); if (memcmp(seq->tx, seq->rx, 4) == 0) { gpio_set(LED_PIN, 1); //printf("ok, received back the same\n"); } else { gpio_set(LED_PIN, 0); if (seq->rx[0] != 0) printf("%s: %02x %02x %02x %02x\n", __func__, seq->rx[0], seq->rx[1], seq->rx[2], seq->rx[3]); } udelay(10*1000); }

return 0; } </syntaxhighlight>

References

Domen 12:10, 17 April 2011 (UTC)