Dirk (Diskussion | Beiträge) K (→I2C-Slave) |
Dirk (Diskussion | Beiträge) K (→I2C-Slave) |
||
| Zeile 102: | Zeile 102: | ||
=I2C-Slave= | =I2C-Slave= | ||
Hier mal eine erste Version des M32 I2C-Slave. | Hier mal eine erste Version des M32 I2C-Slave. | ||
| + | |||
| + | Bitte testet diese Version! Was sollte noch geändert/verbessert werden? Fehler? | ||
Datei RP6Control_I2CSlave.c: | Datei RP6Control_I2CSlave.c: | ||
Version vom 13. September 2012, 21:15 Uhr
Inhaltsverzeichnis
Planung
Erst mal die Planung:
- 1. Der I2C-Slave für die M32 soll genauso arbeiten, wie der RP6Base I2C-Slave (RP6Base_I2CSlave.c) in den Demos.
- 2. Er soll möglichst (fast) alle Funktionen/Ressourcen der M32 über I2C "fernsteuerbar" bzw. abfragbar machen.
- 3. Er soll als I2C-Master eine andere M32, die CCPRO M128 oder die M256 WiFi akzeptieren.
- 4. Er soll die I2C-Adresse 12 bekommen.
- 5. Er soll über XBUS INT2 mit dem Master verbunden sein.
- 6. Er soll wie der Base-Slave auch eine Timeout-Funktion haben.
- 7. Er soll folgende Befehle (commands) über I2C verstehen:
// Commands: #define CMD_CONFIGIOS 0 #define CMD_SETIOS 1 #define CMD_CONFIG 2 #define CMD_SETLEDS 3 #define CMD_DISCHARGEPEAKDETECTOR 4 #define CMD_GETMICROPHONEPEAK 5 #define CMD_SETMEM_CS2 6 #define CMD_WRITESPI 7 #define CMD_WRITEWORDSPI 8 #define CMD_READSPI 9 #define CMD_READWORDSPI 10 #define CMD_SET_WDT 11 #define CMD_SET_WDT_RQ 12 #define CMD_SET_HEARTBEAT 13 #define CMD_SPI_EEPROM_WRITEBYTE 14 #define CMD_SPI_EEPROM_WRITEWORD 15 #define CMD_SPI_EEPROM_ENABLEWRITE 16 #define CMD_SPI_EEPROM_DISABLEWRITE 17 #define CMD_SPI_EEPROM_READBYTE 18 #define CMD_SPI_EEPROM_READWORD 19 #define CMD_SPI_EEPROM_GETSTATUS 20 #define CMD_INITLCD 21 #define CMD_CLEARLCD 22 #define CMD_CLEARPOSLCD 23 #define CMD_WRITECHARLCD 24 #define CMD_WRITEINTEGERLCD 25 #define CMD_SETCURSORPOSLCD 26 #define CMD_BEEP 27 #define CMD_SETBEEPERPITCH 28 #define CMD_SOUND 29
Dabei setzt Befehl 0 die 8 freien I/O-Pins der M32 als Ein- oder Ausgänge. Befehl 1 schaltet die einzelnen I/O-Portpins. Befehl 2 ist Platzhalter ohne Funktion (z.B. zur Konfiguration des Slave). Befehl 3 schaltet die LEDs. Befehle 4, 5 gehen mit dem Mikro um. Befehle 6-10 sind die SPI-Befehle. Befehle 11,12 gehören zum Watchdog-Timer (wie bei der Base!). Befehl 13 schaltet die LCD Heartbeat (Herzschlag) Funktion. Befehle 14-20 lesen und schreiben von/aus dem SPI-EEPROM auf der M32. Befehle 21-26 steuern das LCD auf der M32 an. Befehle 27-29 steuern den Sound mit dem Beeper.
- 8. Er soll folgende Register zum Lesen durch den Master vorhalten:
#define I2C_REG_STATUS1 0 #define I2C_REG_STATUS2 1 #define I2C_REG_IO_STATUS 2 #define I2C_REG_MEM_CS2 3 #define I2C_REG_SPIBYTE 4 #define I2C_REG_SPIWORD_L 5 #define I2C_REG_SPIWORD_H 6 #define I2C_REG_SPIEEPROMSTATUS 7 #define I2C_REG_SPIEEPROMBYTE 8 #define I2C_REG_SPIEEPROMWORD_L 9 #define I2C_REG_SPIEEPROMWORD_H 10 #define I2C_REG_ADC_4_L 11 #define I2C_REG_ADC_4_H 12 #define I2C_REG_ADC_3_L 13 #define I2C_REG_ADC_3_H 14 #define I2C_REG_ADC_2_L 15 #define I2C_REG_ADC_2_H 16 #define I2C_REG_ADC_6_L 17 #define I2C_REG_ADC_6_H 18 #define I2C_REG_ADC_5_L 19 #define I2C_REG_ADC_5_H 20 #define I2C_REG_ADC_7_L 21 #define I2C_REG_ADC_7_H 22 #define I2C_REG_ADC_MIC_L 23 #define I2C_REG_ADC_MIC_H 24 #define I2C_REG_ADC_KEYPAD_L 25 #define I2C_REG_ADC_KEYPAD_H 26 #define I2C_REG_RELEASEDKEYNUMBER 27 #define I2C_REG_PRESSEDKEYNUMBER 28 #define I2C_REG_LEDS 29
Die REGs 0,1 sind die Interrupt- und Status-Register wie beim Base-Slave. IO-Status (REG 2) sind die 8 freien I/O-Ports (sofern auf Eingänge geschaltet). REGs 3-10 sind Leseregister der SPI- und SPI-EEPROM-Funktionen. REGs 11-22 sind die freien ADC-Kanäle der M32. REGs 23,24 sind der ADC-Wert des Mikro. REGs 25,26 sind der ADC-Keypad-Wert. REGs 27,28 sind die Nummern der zuletzt losgelassenen bzw. gedrückten Taste. Mit REG 29 läßt sich der aktuelle Stand der 4 LEDs auslesen (an/aus).
- 9. Er soll auf die RP6Control Library V1.32beta aufsetzen. Grund: Die aktuelle Lib V1.32beta ist voll kompatibel zur neuesten Version 1.3 und stellt mit eigenen Tasks schon regelmäßig die ADC-Werte und Werte der I/O-Ports zur Verfügung.
- 10. Bei Timeout soll die M32 funktionsfähig bleiben (Base-Slave bleibt dann in einer Endlosschleife stehen und muss resettet werden!).
I2C-Slave
Hier mal eine erste Version des M32 I2C-Slave.
Bitte testet diese Version! Was sollte noch geändert/verbessert werden? Fehler?
Datei RP6Control_I2CSlave.c:
/*
* ****************************************************************************
* RP6 ROBOT SYSTEM - RP6 CONTROL M32 EXAMPLES
* ****************************************************************************
* Example: I2C Slave
* Author(s): Dirk
* ****************************************************************************
* Description:
*
* A very common thing that many users will want to do with their M32 is
* to control it with a second controller which has more free resources.
* (more free memory, free I/O Ports and ADCs, faster, etc. pp.
* for example the RP6 C-Control PRO M128 or M256 WIFI expansion Module)
*
* This programs allows you to control the RP6 CONTROL M32 completely via
* I2C-Bus as a slave device!
*
* ############################################################################
* The Robot does NOT move in this example! You can simply put it on a table
* next to your PC and you should connect it to the PC via the USB Interface!
* ############################################################################
* ****************************************************************************
*/
/*****************************************************************************/
// Includes:
#include "RP6ControlLib.h" // The RP6 Control Library v1.32beta.
// Always needs to be included!
#include "RP6I2CslaveTWI.h" // Include the I²C-Bus Slave Library
/*****************************************************************************/
// The Slave Address on the I2C Bus can be specified here:
#define RP6Control_I2C_SLAVE_ADR 12
/*****************************************************************************/
// This bitfield contains the main interrupt event status bits. This can be
// read out and any Master devices can react on the specific events.
union {
uint8_t byte;
struct {
uint8_t timeout:1;
uint8_t mem_cs2Change:1;
uint8_t insChange:1;
uint8_t keyChange:1;
uint8_t keypressed:1;
uint8_t unused:3;
};
} interrupt_status;
// Some status bits with current settings and other things.
union {
uint8_t byte;
struct {
uint8_t old_mem_cs2:1;
uint8_t mem_cs2:1;
uint8_t watchDogTimer:1;
uint8_t wdtRequest:1;
uint8_t wdtRequestEnable:1;
uint8_t heartbeat:1;
uint8_t unused:2;
};
} status;
/*****************************************************************************/
/**
* Generates Interrupt Signal and starts Software Watchdog
*/
void signalInterrupt(void)
{
I2CTWI_dataWasRead = 0;
DDRD |= EINT2; // XBUS INT2
PORTD |= EINT2;
if(status.watchDogTimer)
startStopwatch2();
}
/**
* Clears Interrupt
*/
void clearInterrupt(void)
{
stopStopwatch2();
setStopwatch2(0);
status.wdtRequest = false;
PORTD &= ~EINT2; // XBUS INT2
DDRD &= ~EINT2;
}
freeIOs_t old_ins;
uint8_t old_releasedKeyNumber;
uint8_t update_count = 0;
/**
* This function needs to be called frequently in the main loop. It updates
* some values (currently only mem_cs2Change, insChange, keyChange and
* keypressed status, but this may be expanded in future).
*/
void task_update(void)
{
if(getStopwatch4() > 250)
{
// Update mem_cs2 status:
status.mem_cs2 = PINB & MEM_CS2;
update_count++;
setStopwatch4(0);
}
if(update_count > 5)
{
// Update mem_cs2Change:
if(!interrupt_status.mem_cs2Change
&& (status.mem_cs2 != status.old_mem_cs2))
{
status.old_mem_cs2 = status.mem_cs2;
interrupt_status.mem_cs2Change = true;
signalInterrupt();
}
else if(interrupt_status.mem_cs2Change
&& (status.mem_cs2 == status.old_mem_cs2))
{
interrupt_status.mem_cs2Change = false;
signalInterrupt();
}
// Update insChange:
if(!interrupt_status.insChange && (ins.byte != old_ins.byte))
{
old_ins = ins;
interrupt_status.insChange = true;
signalInterrupt();
}
else if(interrupt_status.insChange && (ins.byte == old_ins.byte))
{
interrupt_status.insChange = false;
signalInterrupt();
}
// Update keyChange:
if(!interrupt_status.keyChange
&& (releasedKeyNumber != old_releasedKeyNumber))
{
old_releasedKeyNumber = releasedKeyNumber;
interrupt_status.keyChange = true;
signalInterrupt();
}
else if(interrupt_status.keyChange
&& (releasedKeyNumber == old_releasedKeyNumber))
{
interrupt_status.keyChange = false;
signalInterrupt();
}
update_count = 0;
}
// Update keypressed status:
interrupt_status.keypressed = pressedKeyNumber;
}
/*****************************************************************************/
// I2C Registers that can be read by the Master. Their names should
// be self-explanatory and directly relate to the equivalent variables/functions
// in the RP6Library
#define I2C_REG_STATUS1 0
#define I2C_REG_STATUS2 1
#define I2C_REG_IO_STATUS 2
#define I2C_REG_MEM_CS2 3
#define I2C_REG_SPIBYTE 4
#define I2C_REG_SPIWORD_L 5
#define I2C_REG_SPIWORD_H 6
#define I2C_REG_SPIEEPROMSTATUS 7
#define I2C_REG_SPIEEPROMBYTE 8
#define I2C_REG_SPIEEPROMWORD_L 9
#define I2C_REG_SPIEEPROMWORD_H 10
#define I2C_REG_ADC_4_L 11
#define I2C_REG_ADC_4_H 12
#define I2C_REG_ADC_3_L 13
#define I2C_REG_ADC_3_H 14
#define I2C_REG_ADC_2_L 15
#define I2C_REG_ADC_2_H 16
#define I2C_REG_ADC_6_L 17
#define I2C_REG_ADC_6_H 18
#define I2C_REG_ADC_5_L 19
#define I2C_REG_ADC_5_H 20
#define I2C_REG_ADC_7_L 21
#define I2C_REG_ADC_7_H 22
#define I2C_REG_ADC_MIC_L 23
#define I2C_REG_ADC_MIC_H 24
#define I2C_REG_ADC_KEYPAD_L 25
#define I2C_REG_ADC_KEYPAD_H 26
#define I2C_REG_RELEASEDKEYNUMBER 27
#define I2C_REG_PRESSEDKEYNUMBER 28
#define I2C_REG_LEDS 29
// These variables contain the results of the functions readSPI(),
// readWordSPI(), SPI_EEPROM_readByte[s](), SPI_EEPROM_getStatus() after the
// Master sent one of the commands CMD_READSPI, CMD_READWORDSPI,
// CMD_SPI_EEPROM_READBYTE/WORD, CMD_SPI_EEPROM_GETSTATUS. So these variables
// are updated only "on demand" and NOT permanently!
uint8_t spibyte;
uint16_t spiword;
uint8_t spieepromstatus;
uint8_t spieeprombyte;
uint16_t spieepromword;
/**
* This very important function updates ALL registers that the Master can read.
* It is called frequently out of the Main loop.
*/
void task_updateRegisters(void)
{
if(!I2CTWI_readBusy)
{
I2CTWI_readRegisters[I2C_REG_STATUS1] = (uint8_t)(interrupt_status.byte);
I2CTWI_readRegisters[I2C_REG_STATUS2] = (uint8_t)(status.byte);
I2CTWI_readRegisters[I2C_REG_IO_STATUS] = (uint8_t)(ins.byte);
I2CTWI_readRegisters[I2C_REG_MEM_CS2] = (uint8_t)(status.mem_cs2);
I2CTWI_readRegisters[I2C_REG_SPIBYTE] = (uint8_t)(spibyte);
I2CTWI_readRegisters[I2C_REG_SPIWORD_L] = (uint8_t)(spiword);
I2CTWI_readRegisters[I2C_REG_SPIWORD_H] = (uint8_t)(spiword>>8);
I2CTWI_readRegisters[I2C_REG_SPIEEPROMSTATUS] = (uint8_t)(spieepromstatus);
I2CTWI_readRegisters[I2C_REG_SPIEEPROMBYTE] = (uint8_t)(spieeprombyte);
I2CTWI_readRegisters[I2C_REG_SPIEEPROMWORD_L] = (uint8_t)(spieepromword);
I2CTWI_readRegisters[I2C_REG_SPIEEPROMWORD_H] = (uint8_t)(spieepromword>>8);
I2CTWI_readRegisters[I2C_REG_ADC_4_L] = (uint8_t)(adc4);
I2CTWI_readRegisters[I2C_REG_ADC_4_H] = (uint8_t)(adc4>>8);
I2CTWI_readRegisters[I2C_REG_ADC_3_L] = (uint8_t)(adc3);
I2CTWI_readRegisters[I2C_REG_ADC_3_H] = (uint8_t)(adc3>>8);
I2CTWI_readRegisters[I2C_REG_ADC_2_L] = (uint8_t)(adc2);
I2CTWI_readRegisters[I2C_REG_ADC_2_H] = (uint8_t)(adc2>>8);
I2CTWI_readRegisters[I2C_REG_ADC_6_L] = (uint8_t)(adc6);
I2CTWI_readRegisters[I2C_REG_ADC_6_H] = (uint8_t)(adc6>>8);
I2CTWI_readRegisters[I2C_REG_ADC_5_L] = (uint8_t)(adc5);
I2CTWI_readRegisters[I2C_REG_ADC_5_H] = (uint8_t)(adc5>>8);
I2CTWI_readRegisters[I2C_REG_ADC_7_L] = (uint8_t)(adc7);
I2CTWI_readRegisters[I2C_REG_ADC_7_H] = (uint8_t)(adc7>>8);
I2CTWI_readRegisters[I2C_REG_ADC_MIC_L] = (uint8_t)(adcMic);
I2CTWI_readRegisters[I2C_REG_ADC_MIC_H] = (uint8_t)(adcMic>>8);
I2CTWI_readRegisters[I2C_REG_ADC_KEYPAD_L] = (uint8_t)(adcKeypad);
I2CTWI_readRegisters[I2C_REG_ADC_KEYPAD_H] = (uint8_t)(adcKeypad>>8);
I2CTWI_readRegisters[I2C_REG_RELEASEDKEYNUMBER] = (uint8_t)(releasedKeyNumber);
I2CTWI_readRegisters[I2C_REG_PRESSEDKEYNUMBER] = (uint8_t)(pressedKeyNumber);
I2CTWI_readRegisters[I2C_REG_LEDS] = (uint8_t)(externalPort.LEDS);
if(I2CTWI_dataWasRead && I2CTWI_dataReadFromReg == 0)
clearInterrupt();
}
}
/*****************************************************************************/
// Command Registers - these can be written by the Master.
// The other registers (read registers) can NOT be written to. The only way to
// communicate with the M32 is via specific commands.
// Of course you can also add more registers if you like...
// ----------------------
#define I2C_REGW_CMD 0
#define I2C_REGW_CMD_PARAM1 1
#define I2C_REGW_CMD_PARAM2 2
#define I2C_REGW_CMD_PARAM3 3
#define I2C_REGW_CMD_PARAM4 4
#define I2C_REGW_CMD_PARAM5 5
#define I2C_REGW_CMD_PARAM6 6
// ----------------------
uint8_t cmd;
uint8_t param1;
uint8_t param2;
uint8_t param3;
uint8_t param4;
uint8_t param5;
uint8_t param6;
/**
* Checks if a new Command has been received and also reads all
* paramters associated with this command.
* It returns true if a new command has been received.
*/
uint8_t getCommand(void)
{
if(I2CTWI_writeRegisters[I2C_REGW_CMD] && !I2CTWI_writeBusy)
{
cmd = I2CTWI_writeRegisters[I2C_REGW_CMD]; // store command register
I2CTWI_writeRegisters[I2C_REGW_CMD] = 0; // clear command register (!!!)
param1 = I2CTWI_writeRegisters[I2C_REGW_CMD_PARAM1]; // parameters 1-6...
param2 = I2CTWI_writeRegisters[I2C_REGW_CMD_PARAM2];
param3 = I2CTWI_writeRegisters[I2C_REGW_CMD_PARAM3];
param4 = I2CTWI_writeRegisters[I2C_REGW_CMD_PARAM4];
param5 = I2CTWI_writeRegisters[I2C_REGW_CMD_PARAM5];
param6 = I2CTWI_writeRegisters[I2C_REGW_CMD_PARAM6];
return true;
}
return false;
}
/*****************************************************************************/
// Command processor:
// Commands:
#define CMD_CONFIGIOS 0
#define CMD_SETIOS 1
#define CMD_CONFIG 2
#define CMD_SETLEDS 3
#define CMD_DISCHARGEPEAKDETECTOR 4
#define CMD_GETMICROPHONEPEAK 5
#define CMD_SETMEM_CS2 6
#define CMD_WRITESPI 7
#define CMD_WRITEWORDSPI 8
#define CMD_READSPI 9
#define CMD_READWORDSPI 10
#define CMD_SET_WDT 11
#define CMD_SET_WDT_RQ 12
#define CMD_SET_HEARTBEAT 13
#define CMD_SPI_EEPROM_WRITEBYTE 14
#define CMD_SPI_EEPROM_WRITEWORD 15
#define CMD_SPI_EEPROM_ENABLEWRITE 16
#define CMD_SPI_EEPROM_DISABLEWRITE 17
#define CMD_SPI_EEPROM_READBYTE 18
#define CMD_SPI_EEPROM_READWORD 19
#define CMD_SPI_EEPROM_GETSTATUS 20
#define CMD_INITLCD 21
#define CMD_CLEARLCD 22
#define CMD_CLEARPOSLCD 23
#define CMD_WRITECHARLCD 24
#define CMD_WRITEINTEGERLCD 25
#define CMD_SETCURSORPOSLCD 26
#define CMD_BEEP 27
#define CMD_SETBEEPERPITCH 28
#define CMD_SOUND 29
uint8_t rw_buffer[3];
/**
* This function checks if commands have been received and processes them.
*/
void task_commandProcessor(void)
{
if(getCommand())
{
switch(cmd)
{
case CMD_CONFIGIOS: if(param1) setFreeIOsToOUT(); else setFreeIOsToIN(); break;
case CMD_SETIOS: setOUTs(param1); break;
case CMD_CONFIG: break;
case CMD_SETLEDS: setLEDs(param1); break;
case CMD_DISCHARGEPEAKDETECTOR: dischargePeakDetector(); break;
case CMD_GETMICROPHONEPEAK: adcMic = getMicrophonePeak(); break;
case CMD_SETMEM_CS2: if(param1) PORTB |= MEM_CS2; else PORTB &= ~MEM_CS2; break;
case CMD_WRITESPI: writeSPI(param1); break;
case CMD_WRITEWORDSPI: writeWordSPI((param1<<8)+param2); break;
case CMD_READSPI: spibyte = readSPI(); break;
case CMD_READWORDSPI: spiword = readWordSPI(); break;
case CMD_SET_WDT: status.watchDogTimer = param1 ? true : false; break;
case CMD_SET_WDT_RQ: status.wdtRequestEnable = param1 ? true : false; break;
case CMD_SET_HEARTBEAT: status.heartbeat = param1 ? true : false; break;
case CMD_SPI_EEPROM_WRITEBYTE: SPI_EEPROM_writeByte((param1<<8)+param2, param3); break;
case CMD_SPI_EEPROM_WRITEWORD: rw_buffer[0] = param3; rw_buffer[1] = param4;
SPI_EEPROM_writeBytes((param1<<8)+param2, &rw_buffer[0], 2); break;
case CMD_SPI_EEPROM_ENABLEWRITE: SPI_EEPROM_enableWrite(); break;
case CMD_SPI_EEPROM_DISABLEWRITE: SPI_EEPROM_disableWrite(); break;
case CMD_SPI_EEPROM_READBYTE: spieeprombyte = SPI_EEPROM_readByte((param1<<8)+param2); break;
case CMD_SPI_EEPROM_READWORD: SPI_EEPROM_readBytes((param1<<8)+param2, &rw_buffer[0], 2);
spieepromword = (rw_buffer[0]<<8)+rw_buffer[1]; break;
case CMD_SPI_EEPROM_GETSTATUS: spieepromstatus = SPI_EEPROM_getStatus(); break;
case CMD_INITLCD: initLCD(); break;
case CMD_CLEARLCD: clearLCD(); break;
case CMD_CLEARPOSLCD: clearPosLCD(param1, param2, param3); break;
case CMD_WRITECHARLCD: writeCharLCD(param1); break;
case CMD_WRITEINTEGERLCD: writeIntegerLCD((param1<<8)+param2, param3); break;
case CMD_SETCURSORPOSLCD: setCursorPosLCD(param1, param2); break;
case CMD_BEEP: beep(param1, (param2<<8)+param3); break;
case CMD_SETBEEPERPITCH: setBeeperPitch(param1); break;
case CMD_SOUND: sound(param1, (param2<<8)+param3, (param4<<8)+param5); break;
}
}
}
/**
* This is the Software watchdog function. After any interrupt event, a timer is
* started and if a certain amount of time has passed by with no reaction from
* the Master, the RP6 CONTROL M32 shows this by blinking with status LEDs 1..4
* for 3 seconds. After this the interrupt and interrupt status are cleared.
* Usually the Master program has errors or is locked up if it does not react,
* so the blinking LEDs show, that there is a communication problem.
*/
void task_MasterTimeout(void)
{
if(status.watchDogTimer)
{
static uint8_t blinkflag = 0;
if(getStopwatch2() > 3000) // 3 seconds timeout for the master to react on
{ // our interrupt events - if he does not react, we
// blink with LEDs 1..4 for another 3 seconds!
interrupt_status.timeout = true;
if(getStopwatch2() > 6000)
{
setLEDs(0b0000); // Clear LEDs
interrupt_status.byte = 0; // Clear interrupt status
setStopwatch4(0);
clearInterrupt(); // Clear interrupt
}
}
else if(getStopwatch3() > 250)
{
status.wdtRequest = true;
signalInterrupt();
setStopwatch3(0);
}
if(interrupt_status.timeout)
{
if(getStopwatch5() > 200)
{
if(blinkflag)
{
setLEDs(0b1001);
blinkflag = 0;
}
else
{
setLEDs(0b0110);
blinkflag = 1;
}
setStopwatch5(0);
}
}
}
}
/**
* LCD Heartbeat function
*/
void task_LCDHeartbeat(void)
{
if(status.heartbeat)
{
if(getStopwatch1() > 500)
{
static uint8_t heartbeat = false;
if(heartbeat)
{
clearPosLCD(1, 15, 1);
heartbeat = false;
}
else
{
setCursorPosLCD(1, 15);
writeStringLCD_P("*");
heartbeat = true;
}
setStopwatch1(0);
}
}
}
/*****************************************************************************/
// Main - The program starts here:
int16_t main(void)
{
initRP6Control();
setLEDs(0b1111);
mSleep(500);
setLEDs(0b0000);
I2CTWI_initSlave(RP6Control_I2C_SLAVE_ADR);
status.byte = 0;
interrupt_status.byte = 0;
// TEST TEST TEST TEST TEST TEST
status.watchDogTimer = true;
status.heartbeat = true;
// TEST TEST TEST TEST TEST TEST
startStopwatch1(); // For LCDHeartbeat function
startStopwatch3();
startStopwatch4();
startStopwatch5();
while(true)
{
task_commandProcessor();
task_update();
task_updateRegisters();
task_RP6M32System();
task_MasterTimeout();
task_LCDHeartbeat();
}
return 0;
}
I2C-Master (RP6v2 M256 WiFi)
Siehe auch
Weblinks
Autoren
--Dirk 19:20, 12. Sep 2012 (CET)