29
29
@brief HID Keyboard project that can be used as a template for new projects.
30
30
31
31
@details
32
+
33
+ IMPORTANT: This example still is not compatible with CHIPKIT
34
+
32
35
This project is a firmware template for new HID keyboard projects which need to use 2 bonds.
33
36
The project will run correctly in its current state.
34
37
This will show the Arduino board as a HID Keybaord to the Win 8.
35
38
After HID Keyboard has been bonded with Win 8.
36
- The letter 'a ' is sent to the Win 8 every 4 seconds.
39
+ The letter 'A ' is sent to the Win 8 every 4 seconds.
37
40
With this project you have a starting point for adding your own application functionality.
38
41
39
42
The following instructions describe the steps to be made on the Windows PC:
@@ -45,7 +48,7 @@ The following instructions describe the steps to be made on the Windows PC:
45
48
the required buttons for I/O.
46
49
47
50
Note:
48
- Pin #8 on Arduino -> PAIRING CLEAR pin: Connect to 3.3v to clear the pairing
51
+ Pin #6 on Arduino -> PAIRING CLEAR pin: Connect to 3.3v to clear the pairing
49
52
Pin #2 on Arduino -> Add new bond pin: Connect to 3.3v to add a new bond.
50
53
51
54
The bonding information is stored in the EEPROM of the ATmega328 in the Arduino UNO
@@ -90,7 +93,6 @@ static struct aci_state_t aci_state;
90
93
static hal_aci_evt_t aci_data;
91
94
static hal_aci_data_t aci_cmd;
92
95
93
-
94
96
/*
95
97
We will store the bonding info for the nRF8001 in the MCU to recover from a power loss situation
96
98
*/
@@ -153,26 +155,25 @@ FUNC ***/
153
155
154
156
void Timer1start ()
155
157
{
158
+ // Setup Timer1 overflow to fire every 4000ms
159
+ // period [sec] = (1 / f_clock [sec]) * prescale * (count)
160
+ // (1/16000000) * 1024 * (count) = 4000 ms
156
161
157
- // Setup Timer1 overflow to fire every 4000ms
158
- // period [sec] = (1 / f_clock [sec]) * prescale * (count)
159
- // (1/16000000) * 1024 * (count) = 4000 ms
160
162
163
+ TCCR1B = 0x00 ; // Disable Timer1 while we set it up
161
164
162
- TCCR1B = 0x00 ; // Disable Timer1 while we set it up
163
-
164
- TCNT1H = 11 ; // Approx 4000ms when prescaler is set to 1024
165
- TCNT1L = 0 ;
166
- TIFR1 = 0x00 ; // Timer1 INT Flag Reg: Clear Timer Overflow Flag
167
- TIMSK1 = 0x01 ; // Timer1 INT Reg: Timer1 Overflow Interrupt Enable
168
- TCCR1A = 0x00 ; // Timer1 Control Reg A: Wave Gen Mode normal
169
- TCCR1B = 0x05 ; // Timer1 Control Reg B: Timer Prescaler set to 1024
165
+ TCNT1H = 11 ; // Approx 4000ms when prescaler is set to 1024
166
+ TCNT1L = 0 ;
167
+ TIFR1 = 0x00 ; // Timer1 INT Flag Reg: Clear Timer Overflow Flag
168
+ TIMSK1 = 0x01 ; // Timer1 INT Reg: Timer1 Overflow Interrupt Enable
169
+ TCCR1A = 0x00 ; // Timer1 Control Reg A: Wave Gen Mode normal
170
+ TCCR1B = 0x05 ; // Timer1 Control Reg B: Timer Prescaler set to 1024
170
171
}
171
172
172
173
void Timer1stop ()
173
174
{
174
- TCCR1B = 0x00 ;
175
- TIMSK1 = 0x00 ;
175
+ TCCR1B = 0x00 ;
176
+ TIMSK1 = 0x00 ;
176
177
}
177
178
178
179
/* ** FUNC
@@ -185,14 +186,14 @@ FUNC ***/
185
186
186
187
ISR (TIMER1_OVF_vect)
187
188
{
188
- if (0 == timer1_f)
189
- {
190
- timer1_f = 1 ;
191
- }
189
+ if (0 == timer1_f)
190
+ {
191
+ timer1_f = 1 ;
192
+ }
192
193
193
- TCNT1H = 11 ; // Approx 4000 ms - Reload
194
- TCNT1L = 0 ;
195
- TIFR1 = 0x00 ; // timer1 int flag reg: clear timer overflow flag
194
+ TCNT1H = 11 ; // Approx 4000 ms - Reload
195
+ TCNT1L = 0 ;
196
+ TIFR1 = 0x00 ; // timer1 int flag reg: clear timer overflow flag
196
197
};
197
198
198
199
/* Define how assert should function in the BLE library */
@@ -270,8 +271,8 @@ aci_status_code_t bond_data_restore(aci_state_t *aci_stat, uint8_t bond_index)
270
271
271
272
for (uint8_t i=1 ; i<=len; i++)
272
273
{
273
- aci_cmd.buffer [i] = EEPROM.read (eeprom_offset_read);
274
- eeprom_offset_read++;
274
+ aci_cmd.buffer [i] = EEPROM.read (eeprom_offset_read);
275
+ eeprom_offset_read++;
275
276
}
276
277
277
278
// @todo : Fix this bug that is changing this byte
@@ -293,10 +294,10 @@ aci_status_code_t bond_data_restore(aci_state_t *aci_stat, uint8_t bond_index)
293
294
294
295
if (ACI_EVT_CMD_RSP != aci_evt->evt_opcode )
295
296
{
296
- // Got something other than a command response evt -> Error
297
- Serial.print (F (" bond_data_restore: Expected cmd rsp evt. Got: 0x" ));
298
- Serial.println (aci_evt->evt_opcode , HEX);
299
- return ACI_STATUS_ERROR_INTERNAL;
297
+ // Got something other than a command response evt -> Error
298
+ Serial.print (F (" bond_data_restore: Expected cmd rsp evt. Got: 0x" ));
299
+ Serial.println (aci_evt->evt_opcode , HEX);
300
+ return ACI_STATUS_ERROR_INTERNAL;
300
301
}
301
302
else
302
303
{
@@ -320,7 +321,6 @@ aci_status_code_t bond_data_restore(aci_state_t *aci_stat, uint8_t bond_index)
320
321
}
321
322
}
322
323
}
323
-
324
324
}
325
325
}
326
326
@@ -332,8 +332,6 @@ Uses the global static int eeprom_write_offset to track the EEPROM write offse
332
332
*/
333
333
void bond_data_store (aci_evt_t *evt)
334
334
{
335
-
336
-
337
335
// Write it to non-volatile storage
338
336
EEPROM.write ( eeprom_write_offset, evt->len -2 );
339
337
eeprom_write_offset++;
@@ -436,13 +434,13 @@ void aci_loop()
436
434
switch (aci_evt->params .device_started .device_mode )
437
435
{
438
436
case ACI_DEVICE_SETUP:
439
- /* *
440
- When the device is in the setup mode
441
- */
442
- aci_state.device_state = ACI_DEVICE_SETUP;
443
- Serial.println (F (" Evt Device Started: Setup" ));
444
- setup_required = true ;
445
- break ;
437
+ /* *
438
+ When the device is in the setup mode
439
+ */
440
+ aci_state.device_state = ACI_DEVICE_SETUP;
441
+ Serial.println (F (" Evt Device Started: Setup" ));
442
+ setup_required = true ;
443
+ break ;
446
444
447
445
case ACI_DEVICE_STANDBY:
448
446
Serial.println (F (" Evt Device Started: Standby" ));
@@ -503,7 +501,7 @@ void aci_loop()
503
501
break ;
504
502
}
505
503
}
506
- break ; // ACI Device Started Event
504
+ break ; // ACI Device Started Event
507
505
508
506
case ACI_EVT_CMD_RSP:
509
507
// If an ACI command response event comes with an error -> stop
@@ -598,29 +596,29 @@ void aci_loop()
598
596
*/
599
597
if (ACI_STATUS_ERROR_ADVT_TIMEOUT == aci_evt->params .disconnected .aci_status )
600
598
{
601
- aci_status_code_t bond_restore_status;
599
+ aci_status_code_t bond_restore_status;
602
600
603
- Serial.print (F (" Previous Bond present. Restoring bond " ));
601
+ Serial.print (F (" Previous Bond present. Restoring bond " ));
604
602
605
- // We must have lost power and restarted and must restore the bonding infromation using the ACI Write Dynamic Data
606
- // Switch to the next bond
607
- Serial.println (current_bond_index);
608
- if (current_bond_index >= BONDS_MAX)
609
- {
610
- current_bond_index = 0 ;
611
- }
612
- bond_restore_status = bond_data_restore (&aci_state, current_bond_index);
613
- current_bond_index++;
603
+ // We must have lost power and restarted and must restore the bonding infromation using the ACI Write Dynamic Data
604
+ // Switch to the next bond
605
+ Serial.println (current_bond_index);
606
+ if (current_bond_index >= BONDS_MAX)
607
+ {
608
+ current_bond_index = 0 ;
609
+ }
610
+ bond_restore_status = bond_data_restore (&aci_state, current_bond_index);
611
+ current_bond_index++;
614
612
615
- if (ACI_STATUS_TRANSACTION_COMPLETE == bond_restore_status)
616
- {
617
- Serial.println (F (" Bond restored successfully" ));
618
- }
619
- if (BOND_DOES_NOT_EXIST_AT_INDEX == bond_restore_status)
620
- {
621
- Serial.println (F (" Bond does not exist" ));
622
- current_bond_index = 0 ;
623
- }
613
+ if (ACI_STATUS_TRANSACTION_COMPLETE == bond_restore_status)
614
+ {
615
+ Serial.println (F (" Bond restored successfully" ));
616
+ }
617
+ if (BOND_DOES_NOT_EXIST_AT_INDEX == bond_restore_status)
618
+ {
619
+ Serial.println (F (" Bond does not exist" ));
620
+ current_bond_index = 0 ;
621
+ }
624
622
}
625
623
else
626
624
{
@@ -647,18 +645,17 @@ void aci_loop()
647
645
}
648
646
}
649
647
650
-
651
648
// If a new bond is to be added, PIN 2 must tbe high or no bond exists
652
649
if (0x01 == digitalRead (2 ) || (0 == bond_number))
653
650
{
654
- // Start bonding
655
- // Less than 2 bonds. We can add one more
656
- if (bond_number < BONDS_MAX)
657
- {
658
- // Previous bonding failed. Try to bond again.
659
- lib_aci_bond (180 /* in seconds */ , 0x0050 /* advertising interval 50ms*/ );
660
- Serial.println (F (" Advertising started : Waiting to be connected and bonded for a new bond to be added" ));
661
- }
651
+ // Start bonding
652
+ // Less than 2 bonds. We can add one more
653
+ if (bond_number < BONDS_MAX)
654
+ {
655
+ // Previous bonding failed. Try to bond again.
656
+ lib_aci_bond (180 /* in seconds */ , 0x0050 /* advertising interval 50ms*/ );
657
+ Serial.println (F (" Advertising started : Waiting to be connected and bonded for a new bond to be added" ));
658
+ }
662
659
}
663
660
else
664
661
{
@@ -690,7 +687,7 @@ void aci_loop()
690
687
691
688
for (uint8_t counter = 0 ; counter <= (aci_evt->len - 3 ); counter++)
692
689
{
693
- Serial.write (aci_evt->params .hw_error .file_name [counter]); // uint8_t file_name[20];
690
+ Serial.write (aci_evt->params .hw_error .file_name [counter]); // uint8_t file_name[20];
694
691
}
695
692
Serial.println ();
696
693
@@ -765,16 +762,22 @@ void aci_loop()
765
762
}
766
763
}
767
764
768
-
769
-
770
-
771
-
772
765
/*
773
766
This is called only once after a reset of the AVR
774
767
*/
775
768
void setup (void )
776
769
{
777
770
Serial.begin (115200 );
771
+ // Wait until the serial port is available (useful only for the Leonardo)
772
+ // As the Leonardo board is not reseted every time you open the Serial Monitor
773
+ #if defined (__AVR_ATmega32U4__)
774
+ while (!Serial)
775
+ {}
776
+ delay (5000 ); // 5 seconds delay for enabling to see the start up comments on the serial board
777
+ #elif defined(__PIC32MX__)
778
+ delay (1000 );
779
+ #endif
780
+
778
781
Serial.println (F (" Arduino setup" ));
779
782
780
783
/* *
@@ -803,14 +806,15 @@ void setup(void)
803
806
aci_state.aci_pins .miso_pin = MISO;
804
807
aci_state.aci_pins .sck_pin = SCK;
805
808
806
- aci_state.aci_pins .spi_clock_divider = SPI_CLOCK_DIV8;
809
+ aci_state.aci_pins .spi_clock_divider = SPI_CLOCK_DIV8;// SPI_CLOCK_DIV8 = 2MHz SPI speed
810
+ // SPI_CLOCK_DIV16 = 1MHz SPI speed
807
811
808
- aci_state.aci_pins .reset_pin = 4 ;
809
- aci_state.aci_pins .active_pin = UNUSED;
810
- aci_state.aci_pins .optional_chip_sel_pin = UNUSED;
812
+ aci_state.aci_pins .reset_pin = 4 ;
813
+ aci_state.aci_pins .active_pin = UNUSED;
814
+ aci_state.aci_pins .optional_chip_sel_pin = UNUSED;
811
815
812
- aci_state.aci_pins .interface_is_interrupt = false ;
813
- aci_state.aci_pins .interrupt_number = 1 ;
816
+ aci_state.aci_pins .interface_is_interrupt = false ;
817
+ aci_state.aci_pins .interrupt_number = 1 ;
814
818
815
819
/* * We reset the nRF8001 here by toggling the RESET line connected to the nRF8001
816
820
* and initialize the data structures required to setup the nRF8001
@@ -838,7 +842,6 @@ void setup(void)
838
842
}
839
843
}
840
844
841
-
842
845
/* This is like a main() { while(1) { loop() } }
843
846
*/
844
847
void loop (void )
@@ -861,6 +864,7 @@ void loop(void)
861
864
lib_aci_send_data (PIPE_HID_SERVICE_HID_REPORT_TX, &keypressA[0 ], 8 );
862
865
aci_state.data_credit_available --;
863
866
}
867
+
864
868
if (0x01 == digitalRead (2 ) && (disconnect_started == false ))
865
869
{
866
870
// Disconnect the link by ACI Disconnect
0 commit comments