static status_t cd_ioctl(void* cookie, uint32 op, void* buffer, size_t length) { cd_handle* handle = (cd_handle*)cookie; cd_driver_info *info = handle->info; TRACE("ioctl(op = %lu)\n", op); switch (op) { case B_GET_DEVICE_SIZE: { status_t status = update_capacity(info); if (status != B_OK) return status; size_t size = info->capacity * info->block_size; return user_memcpy(buffer, &size, sizeof(size_t)); } case B_GET_GEOMETRY: { if (buffer == NULL /*|| length != sizeof(device_geometry)*/) return B_BAD_VALUE; device_geometry geometry; status_t status = get_geometry(handle, &geometry); if (status != B_OK) return status; return user_memcpy(buffer, &geometry, sizeof(device_geometry)); } case B_GET_ICON_NAME: return user_strlcpy((char*)buffer, "devices/drive-optical", B_FILE_NAME_LENGTH); case B_GET_VECTOR_ICON: { device_icon iconData; if (length != sizeof(device_icon)) return B_BAD_VALUE; if (user_memcpy(&iconData, buffer, sizeof(device_icon)) != B_OK) return B_BAD_ADDRESS; if (iconData.icon_size >= (int32)sizeof(kCDIcon)) { if (user_memcpy(iconData.icon_data, kCDIcon, sizeof(kCDIcon)) != B_OK) return B_BAD_ADDRESS; } iconData.icon_size = sizeof(kCDIcon); return user_memcpy(buffer, &iconData, sizeof(device_icon)); } case B_SCSI_GET_TOC: // TODO: we pass a user buffer here! return get_toc(info, (scsi_toc *)buffer); case B_EJECT_DEVICE: case B_SCSI_EJECT: return load_eject(info, false); case B_LOAD_MEDIA: return load_eject(info, true); case B_SCSI_GET_POSITION: { if (buffer == NULL) return B_BAD_VALUE; scsi_position position; status_t status = get_position(info, &position); if (status != B_OK) return status; return user_memcpy(buffer, &position, sizeof(scsi_position)); } case B_SCSI_GET_VOLUME: // TODO: we pass a user buffer here! return get_set_volume(info, (scsi_volume *)buffer, false); case B_SCSI_SET_VOLUME: // TODO: we pass a user buffer here! return get_set_volume(info, (scsi_volume *)buffer, true); case B_SCSI_PLAY_TRACK: { scsi_play_track track; if (user_memcpy(&track, buffer, sizeof(scsi_play_track)) != B_OK) return B_BAD_ADDRESS; return play_track_index(info, &track); } case B_SCSI_PLAY_POSITION: { scsi_play_position position; if (user_memcpy(&position, buffer, sizeof(scsi_play_position)) != B_OK) return B_BAD_ADDRESS; return play_msf(info, &position); } case B_SCSI_STOP_AUDIO: return stop_audio(info); case B_SCSI_PAUSE_AUDIO: return pause_resume(info, false); case B_SCSI_RESUME_AUDIO: return pause_resume(info, true); case B_SCSI_SCAN: { scsi_scan scanBuffer; if (user_memcpy(&scanBuffer, buffer, sizeof(scsi_scan)) != B_OK) return B_BAD_ADDRESS; return scan(info, &scanBuffer); } case B_SCSI_READ_CD: // TODO: we pass a user buffer here! return read_cd(info, (scsi_read_cd *)buffer); default: return sSCSIPeripheral->ioctl(handle->scsi_periph_handle, op, buffer, length); } }
int main() { unsigned long T = 0L; int Ival; U8 rb, Num; CFG_GCR |= 1; // disable SWIM // Configure clocking CLK_CKDIVR = 0; // F_HSI = 16MHz, f_CPU = 16MHz // Timer 4 (8 bit) used as system tick timer // prescaler == 128 (2^7), Tfreq = 125kHz // period = 1ms, so ARR = 125 TIM4_PSCR = 7; TIM4_ARR = 125; // interrupts: update TIM4_IER = TIM_IER_UIE; // auto-reload + interrupt on overflow + enable TIM4_CR1 = TIM_CR1_APRE | TIM_CR1_URS | TIM_CR1_CEN; // Configure pins // PC2 - PP output (on-board LED) PORT(LED_PORT, DDR) |= LED_PIN; PORT(LED_PORT, CR1) |= LED_PIN; // PD5 - UART2_TX -- pseudo open-drain output; don't forget an pullup resistor! PORT(UART_PORT, DDR) |= UART_TX_PIN; PORT(UART_PORT, ODR) |= UART_TX_PIN; // torn off N push-down ??? //PORT(UART_PORT, CR1) |= UART_TX_PIN; // Configure UART // 9 bit, no parity, 1 stop (UART_CR3 = 0 - reset value) // 57600 on 16MHz: BRR1=0x11, BRR2=0x06 UART2_BRR1 = 0x11; UART2_BRR2 = 0x06; UART2_CR1 = UART_CR1_M; // M = 1 -- 9bits UART2_CR2 = UART_CR2_REN | UART_CR2_RIEN; // Allow RX, generate ints on rx setup_stepper_pins(); // enable all interrupts enableInterrupts(); // Loop do{ if((Global_time - T > paused_val) || (T > Global_time)){ T = Global_time; PORT(LED_PORT, ODR) ^= LED_PIN; // blink on-board LED } if(UART_read_byte(&rb)){ // buffer isn't empty switch(rb){ case 'h': // help case 'H': uart_write("\nPROTO:\n" "+/-\tLED period\n" "Ex/ex\tset/get end-switches stored\n" "p\tget HW end-switches\n" "Mx\tstop on end-switch\n" "Sx/sx\tset/get Mspeed\n" "mx\tget steps\n" "Px\tpause/resume\n" "Xx\tstop\n" "0..2N\tmove xth motor for N steps\n" "=\tinfinity moving (after 0..2)" "U/u\tset/get U-stepping\n" "I\tget serial ID\n" "N\tchange HW number\n" "n\tshow HW number\n" ); break; case 'I': // get serial id show_uid(); break; case '+': paused_val += 100; if(paused_val > 10000) paused_val = 500; // but not more than 10s break; case '-': paused_val -= 100; if(paused_val < 100) // but not less than 0.1s paused_val = 500; break; case 'E': // set end-switches value if(get_motor_number(&Num)){ if(readInt(&Ival) && (Ival == (Ival & 0x1f))){ if(Num) EPs[Num] = Ival & 0x0f; // 4 bits in motors 1&2 else EPs[0] = Ival; // all 5 bits in motor 0 }else error_msg("bad EP"); } break; case 'e': // get stored end-switches value if(get_motor_number(&Num)){ printUint(&EPs[Num], 1); } break; case 'p': // get hardware end-switches value if(get_motor_number(&Num)){ Num = get_ep_value(Num); printUint(&Num, 1); } break; case 'S': // set stepper speed if(get_motor_number(&Num)){ if(readInt(&Ival) && Ival > MIN_STEP_LENGTH) set_stepper_speed(Num, Ival); else error_msg("bad speed"); } break; case 's': // get stepper speed if(get_motor_number(&Num)) printUint((U8*)&Stepper_speed[Num], 2); break; case 'M': // move till EP, you can call it before starting motor if(get_motor_number(&Num)) Stop_on_EP[Num] = 1; break; case 'm': // how much steps there is to the end of moving if(get_motor_number(&Num)) printUint((U8*)&Nsteps[Num], 2); break; case 'X': // stop if(get_motor_number(&Num)) stop_motor(Num); break; case 'P': // pause/resume if(get_motor_number(&Num)) pause_resume(Num); break; case 'N': if(readInt(&Ival) && Ival > 0 && Ival < 256) if(!change_progmem_value(&UART_devNUM, (unsigned int) Ival)) error_msg("can't change val"); break; case 'n': // show HW num printUint(&UART_devNUM, 1); break; case 'u': // show UStepping printUint(&USteps, 1); break; case 'U': // set UStepping if(readInt(&Ival) && Ival > 0 && Ival < 256) USteps = Ival; break; case '=': // infinity moving: just don't decrement steps StepperInfty = 1; break; default: if(rb >= '0' && rb <= '2'){ // run motor Num = rb - '0'; if(readInt(&Ival) && Ival) move_motor(Num, Ival); else{ error_msg("bad Nsteps"); } } } } }while(1); }
int main() { unsigned long T = 0L; int Ival; U8 rb; CFG_GCR |= 1; // disable SWIM // Configure clocking CLK_CKDIVR = 0; // F_HSI = 16MHz, f_CPU = 16MHz // Configure timer 1 - systick // prescaler = f_{in}/f_{tim1} - 1 // set Timer1 to 1MHz: 1/1 - 1 = 15 TIM1_PSCRH = 0; TIM1_PSCRL = 15; // LSB should be written last as it updates prescaler // auto-reload each 1ms: TIM_ARR = 1000 = 0x03E8 TIM1_ARRH = 0x03; TIM1_ARRL = 0xE8; // interrupts: update TIM1_IER = TIM_IER_UIE; // auto-reload + interrupt on overflow + enable TIM1_CR1 = TIM_CR1_APRE | TIM_CR1_URS | TIM_CR1_CEN; // Configure pins // PC2 - PP output (on-board LED) PORT(LED_PORT, DDR) |= LED_PIN; PORT(LED_PORT, CR1) |= LED_PIN; // PD5 - UART2_TX PORT(UART_PORT, DDR) |= UART_TX_PIN; PORT(UART_PORT, CR1) |= UART_TX_PIN; // Configure UART // 8 bit, no parity, 1 stop (UART_CR1/3 = 0 - reset value) // 57600 on 16MHz: BRR1=0x11, BRR2=0x06 UART2_BRR1 = 0x11; UART2_BRR2 = 0x06; UART2_CR2 = UART_CR2_TEN | UART_CR2_REN | UART_CR2_RIEN; // Allow RX/TX, generate ints on rx // enable all interrupts enableInterrupts(); set_stepper_speed(1000); setup_stepper_pins(); // Loop do{ if((Global_time - T > paused_val) || (T > Global_time)){ T = Global_time; PORT(LED_PORT, ODR) ^= LED_PIN; // blink on-board LED } if(UART_read_byte(&rb)){ // buffer isn't empty switch(rb){ case 'h': // help case 'H': uart_write("\nPROTO:\n+/-\tLED period\nS/s\tset/get Mspeed\n" "m\tget steps\nx\tstop\np\tpause/resume\nM\tmove motor\na\tadd Nstps\n" "u\tunipolar motor\nb\tbipolar motor\n"); break; case '+': paused_val += 100; if(paused_val > 10000) paused_val = 500; // but not more than 10s break; case '-': paused_val -= 100; if(paused_val < 100) // but not less than 0.1s paused_val = 500; break; case 'S': // set stepper speed if(readInt(&Ival) && Ival > MIN_STEP_LENGTH) set_stepper_speed(Ival); else error_msg("bad speed"); break; case 's': // get stepper speed printUint((U8*)&Stepper_speed, 2); break; case 'm': // how much steps there is to the end of moving printUint((U8*)&Nsteps, 4); break; case 'M': // move motor if(Nsteps){ error_msg("moving!"); break; } if(readInt(&Ival) && Ival) move_motor(Ival); else{ error_msg("bad Nsteps"); } break; case 'x': // stop stop_motor(); break; case 'p': // pause/resume pause_resume(); break; case 'a': // add N steps if(readInt(&Ival) && Ival){ add_steps(Ival); }else{ error_msg("bad value"); } break; case 'u': // unipolar usteps = ustepsUNI; break; case 'b': // bipolar usteps = ustepsBIP; break; } } }while(1); }